Google Cloud SQL通过为您生成服务器ca-cert.pem
,client-cert.pem
和client-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实现,那么还有其他一些步骤可以将它们全部放入一个密钥库中,而不需要信任库吗?
答案 0 :(得分:1)
将默认的JRE cacerts
文件复制到新的信任库,并将服务器证书添加到该信任库。用于所有客户。将此作为构建步骤并在每次升级JRE时重复,因此您不会错过默认cacerts.
当然,如果服务器证书由认可的CA正确签名,则无需将其导入任何位置,也无需使用自定义信任库。如果它没有被认可的CA签名,那么它应该是。