我正在使用 SSL 握手连接到 URL。 为此,我生成了一个 .csr 文件并对其进行了签名。 签名后,我创建了一个 my.jks 文件,其中包含 3 个条目
我使用 jetty 作为服务器,并且我专门将密钥库和信任库设置为相同的 jks 文件,如下所示
-Djavax.net.ssl.keyStore=/home/keystore/my.jks
-Djavax.net.ssl.keyStorePassword=changeit
-Djavax.net.ssl.trustStore=/home/keystore/my.jks
-Djavax.net.ssl.trustStorePassword=changeit
效果很好。但这是正确的做法吗? 我认为密钥库应该包含客户端证书和私钥,信任库应该包含 CA。但是当我尝试这样做时,我收到以下错误。
“javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:PKIX 路径构建失败: sun.security.provider.certpath.SunCertPathBuilderException:无法 找到请求目标的有效认证路径”
请对此提出建议。
不。信任库只包含公共数据:您信任的 CA 的公共证书。 KeyStore 包含私钥及其证书:您的数字身份。他们甚至可能由不同的人控制。不要混淆它们的功能。
如果您想对证书进行自签名(仅当您将其用于服务器内通信而不交换任何个人/敏感信息时):
1) 使用 -certreq 生成 CSR
keytool -certreq -alias keyAlias -keystore locationPk -storepass yourpass -file myowncertrequest.csr
2)使用上面的csr生成证书:
keytool -gencert -infile myowncertrequest.csr -alias keyAlias -keystore locationPk -storepass yourpass -outfile myownsignedcert.cer
3)将其导入“单独的”信任存储
keytool -import -trustcacerts -alias myown -file myownsignedcert.cer -keystore intra_server_truststore -storepass goodpassword
这将创建一个自定义信任存储,该存储仅在您自己的域中使用以及用于一些基本的身份验证和数据交换。但如果要将服务暴露给外界,请务必使用适当的 CA 来签署这些证书。
对于你问题的第一部分,我认为这个答案几乎涵盖了它。简而言之,是的,您可以将两者指向同一个文件,不,这不是最佳实践。至于您收到的错误,可能发生的原因有很多,但您可以尝试将 CA 添加到 JAVA_HOME/jre/lib/security 中的 cacerts 文件中。这使得它可用于所有 JAVA 应用程序。