JDBC + SSL:将CA证书,客户端证书和客户端捆绑到单个密钥库文件中

时间:2015-03-24 03:16:16

标签: java mysql ssl jdbc keytool

Google Cloud SQL通过为您生成服务器ca-cert.pemclient-cert.pemclient-key.pem来支持SSL连接。我通过以下步骤设法让我的Java客户端连接到Cloud SQL:

1)将服务器CA证书导入信任库文件:

keytool -import -alias mysqlServerCACert -file ca-cert.pem -keystore truststore

2)将客户端证书和客户端密钥捆绑到一个pkcs12文件中:

openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -out client.p12 -name clientalias -CAfile ca-cert.pem

3)将pkcs12导入密钥库文件:

keytool -importkeystore -deststorepass keystore -destkeystore keystore -srckeystore client.p12 -srcstoretype PKCS12 -srcstorepass keystore -alias clientalias

4)告诉JVM使用我的信任库和密钥库:

-Djavax.net.ssl.keyStore=/path/to/my/keystore \
-Djavax.net.ssl.keyStorePassword=keystore \
-Djavax.net.ssl.trustStore=/path/to/my/truststore \
-Djavax.net.ssl.trustStorePassword=truststore

这一切都有效,但不幸的是它排除了来自其他客户端库的出站HTTPS连接 - 在我的例子中是Firebase Java客户端库。问题是我的-Djavax.net.ssl.trustStore参数覆盖了与JDK捆绑在一起的默认cacerts文件。

我似乎有两种选择。一种不理想的选择是使用特定于操作系统和JDK版本的命令将我的服务器CA证书导入到每个生产和开发机器上的JDK的cacerts文件中。对于真正的生产设置,此选项似乎不实用。

另一种选择是将我的服务器CA证书和客户端证书捆绑到单个(本地)信任链中,然后Java将使用该信任链来验证我的客户端密钥。从我所读过的内容来看,我非常确定这是可能的,但我不知道所需的咒语。

我的猜测是我应该使用单个openssl命令以正确的顺序创建包含我的服务器CA证书,客户端证书和客户端密钥的pkcs12捆绑包,然后使用keytool导入进入一个新的密钥库。我将省略-D.../trustStore JVM参数,并仅指定密钥库参数。 Java会将本地CA信任链用于我的Cloud SQL客户端密钥,但会回退到全局cacerts文件以进行所有其他SSL协商。

这可能吗?如果不能直接作为单个pkcs12实现,那么还有其他一些步骤可以将它们全部放入一个密钥库中,而不需要信任库吗?

1 个答案:

答案 0 :(得分:1)

将默认的JRE cacerts文件复制到新的信任库,并将服务器证书添加到该信任库。用于所有客户。将此作为构建步骤并在每次升级JRE时重复,因此您不会错过默认cacerts.

中的证书更改

当然,如果服务器证书由认可的CA正确签名,则无需将其导入任何位置,也无需使用自定义信任库。如果它没有被认可的CA签名,那么它应该是。