web-dev-qa-db-ja.com

MySQL JDBCは、AWSRDSのクライアント証明書を強制的に無視します

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に正常に接続できますが、keyStoretrustStore

! 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)
5
Rich

接続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が初期化されていません」エラーが表示されます。

5
Rich