【发布时间】:2023-03-07 15:04:01
【问题描述】:
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 文件。
我似乎有两个选择。一种不理想的选择是将我的服务器 CA 证书导入到每台生产和开发机器上的 JDK 的 cacerts 文件中,使用特定于操作系统和特定于 JDK 版本的命令。对于实际的生产设置,此选项似乎不太实用。
另一种选择是将我的服务器 CA 证书和客户端证书捆绑到一个(本地)信任链中,然后 Java 将使用它来验证我的客户端密钥。从我读过的内容来看,我很确定这是可能的,但我不知道所需的咒语。
我的猜测是我应该使用单个 openssl 命令来创建一个 pkcs12 包,其中包含我的服务器 CA 证书、客户端证书和客户端密钥以正确的顺序,然后使用 keytool 将其导入新的密钥库。我会省略-D.../trustStore JVM 参数,只指定密钥库参数。 Java 会为我的 Cloud SQL 客户端密钥使用本地 CA 信任链,但会回退到全局 cacerts 文件以进行所有其他 SSL 协商。
这可能吗?如果不能直接作为单个 pkcs12,那么是否有其他一些步骤可以将它们全部放入单个密钥库中,从而绕过对信任库的需求?
【问题讨论】:
标签: java mysql ssl jdbc keytool