Google Cloud SQL通过为您生成服务器ca-cert.pem
、client-cert.pem
和client-key.pem
来支持SSL连接。我已经通过以下步骤使我的Java客户端连接到云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连接——在我的例子中,是Firebasejava客户端库。问题是我的-Djavax.net.ssl.trustStore
参数覆盖了JDK捆绑的默认cacerts
文件。
我似乎有两种选择。一种不理想的选择是,在每台生产和开发机器上,使用特定于操作系统和特定于JDK版本的命令,将我的服务器CA证书导入JDK的cacerts
文件。对于实际的生产设置来说,这个选项似乎很难实现。
另一种选择是将我的服务器CA证书和客户端证书捆绑到一个(本地)信任链中,然后Java将使用它来验证我的客户端密钥。从我读到的内容来看,我很确定这是可能的,但我不知道所需的咒语。
我的猜测是,我应该使用一个openssl
命令创建一个pkcs12捆绑包,该捆绑包按正确的顺序包含我的服务器CA证书、客户端证书和客户端密钥,然后使用keytool
将其导入到新的密钥库中。我将省略-D.../trustStore
JVM参数,只指定密钥库参数。Java将使用本地CA信任链作为我的Cloud SQL客户端密钥,但将回退到全局cacerts
文件来进行所有其他SSL协商。
这可能吗?如果不能直接作为单个pkcs12,那么是否有其他一些步骤可以将它们全部放入单个密钥库中,从而绕过对信任库的需求?
将默认JRE cacerts
文件复制到新的信任库中,并将服务器证书添加到其中。用于所有客户端。将此步骤作为构建步骤,并在每次JRE升级时重复,这样您就不会错过默认cacerts.
中的证书更改
当然,如果服务器证书由公认的CA正确签名,则无需将其导入任何位置,也无需使用自定义信任库。如果它不是由公认的CA签名的,它应该是.