Java WebアプリをAWSで実行し、AWSRDSで実行されているMySQLデータベースに接続しています。
私のアプリは、独自のCAによって署名されたSSLクライアント証明書を使用してさまざまなWebサービスに接続するため、-Djavax.net.ssl.keyStore
および-Djavax.net.ssl.trustStore
システムプロパティを設定しました。
https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
証明書をtrustStore
に追加しました。コマンドラインクライアント経由でSSLを使用してMySQLに問題なく接続できます。
MySQL接続文字列は次のようになります。
jdbc:mysql://my-server-id.eu-west-1.rds.amazonaws.com/my-database?verifyServerCertificate=true&useSSL=true&requireSSL=true
mysql:mysql-connector-Java:jar:5.1.38
を使用してJBDC接続を実行しています。
trustStore
を設定すると、JavaアプリはMySQLに正常に接続できますが、keyStore
とtrustStore
:
! javax.net.ssl.SSLException: Unsupported record version Unknown-0.0
! at Sun.security.ssl.InputRecord.checkRecordVersion(InputRecord.Java:552) ~[na:1.8.0_91]
! at Sun.security.ssl.InputRecord.readV3Record(InputRecord.Java:565) ~[na:1.8.0_91]
! at Sun.security.ssl.InputRecord.read(InputRecord.Java:532) ~[na:1.8.0_91]
! at Sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.Java:973) ~[na:1.8.0_91]
! at Sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.Java:1375) ~[na:1.8.0_91]
! at Sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.Java:1403) ~[na:1.8.0_91]
! at Sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.Java:1387) ~[na:1.8.0_91]
! at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.Java:149) ~[user-portal-web-0.0.1.jar:0.0.1]
! ... 40 common frames omitted
JavaがMySQLにプライベートCA署名済みクライアント証明書を提示しているようですが、これは拒否されています。tcpdump
とクライアント証明書のDNを使用してインタラクションをキャプチャしましたMySQLに送信されています。
クライアント接続をHTTPS接続に使用できますが、MySQL接続には使用できませんか?
空のキーストアを作成し、それを使用するように接続文字列を設定してみました。
jdbc:mysql://my-server-id.eu-west-1.rds.amazonaws.com/my-database?verifyServerCertificate=true&useSSL=true&requireSSL=true&clientCertificateKeyStoreUrl=file:nokeys.jks&clientCertificateKeyStorePassword=changeit
それは私に次のエラーを与えます:
Java.lang.IllegalStateException: TrustManagerFactoryImpl is not initialized
at Sun.security.ssl.TrustManagerFactoryImpl.engineGetTrustManagers(TrustManagerFactoryImpl.Java:100)
at javax.net.ssl.TrustManagerFactory.getTrustManagers(TrustManagerFactory.Java:285)
at com.mysql.jdbc.ExportControlled.getSSLSocketFactoryDefaultOrConfigured(ExportControlled.Java:323)
at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.Java:85)
接続URLに空のキーストアを設定することで、MySQLがクライアント証明書を使用しないように強制できます。
上記の問題は、バリアント https://bugs.mysql.com/bug.php?id=36948 -接続URLに「clientCertificateKeyStoreUrl」を設定したが、「trustCertificateKeyStoreUrl」も設定しなかった場合"(および以下の4つのその他のパラメーター)の場合、MySQLは、より有用なエラーの代わりに、「TrustManagerFactoryImplが初期化されていません」でクラッシュします。
次のようなコマンドを使用して、空のキーストアを作成できます。
keytool -genkey -alias foo -keystore empty.jks # (set password "changeit")
keytool -delete -alias foo -keystore empty.jks
次に、次のようなURLでMySQLに接続します。
jdbc:mysql://my-server-id.rds.amazonaws.com/my-database?verifyServerCertificate=true&useSSL=true&requireSSL=true&clientCertificateKeyStoreUrl=file:empty.jks&clientCertificateKeyStorePassword=changeit&clientCertificateKeyStoreType=JKS&trustCertificateKeyStoreUrl=file:/etc/pki/cosmos/current/client.jks&trustCertificateKeyStoreType=JKS&trustCertificateKeyStorePassword=changeit
デフォルトが必要な場合でも、6つのキーストア引数すべてが必要です。そうでない場合は、「TrustManagerFactoryImplが初期化されていません」エラーが表示されます。