java - 建立 SSL 主机连接时无法使用签名证书验证 Cacerts

标签 java ssl sslhandshakeexception

<分区>

我已经使用自定义 keystore 和自定义 CA 创建了自定义 cacerts。 我刚刚收到以下异常消息。

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) ~[?:1.7.0_45]
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1884) ~[?:1.7.0_45]
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276) ~[?:1.7.0_45]
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270) ~[?:1.7.0_45]
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341) ~[?:1.7.0_45]
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153) ~[?:1.7.0_45]
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) ~[?:1.7.0_45]
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:804) ~[?:1.7.0_45]
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016) ~[?:1.7.0_45]
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) ~[?:1.7.0_45]
    at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702) ~[?:1.7.0_45]
    at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122) ~[?:1.7.0_45]
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) ~[?:1.7.0_45]
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) ~[?:1.7.0_45]

最佳答案

异常仅说明自定义 keystore 中服务器端的证书链中的证书之一未正确颁发/签名,或者不是放置在客户端的自定义 cacerts 文件的一部分。由于链中存在不受信任的证书,SSL 握手由于缺少正确/良好的证书路径而失败。 要了解此问题的根本原因,请尝试以 PEM 编码格式提取所有中间体、根证书和私钥证书并运行以下命令

请注意,以下内容完全取决于您服务器上安装的 OpenSSL。 (运行 openssl version -a 以显示它是否是您服务器的一部分)

openssl verify -verbose -CAfile <(cat ServerCA1.pem ServerCA2.pem RootCA.pem)
pvtkey_hostORdns_cert.pem

在执行上述命令时,您应该观察到错误为 o/p

如果你的服务器端由多台服务器组成,那么分别登录每台主机运行上面的命令。请参阅以下站点以更深入地了解如何使用 openssl 验证证书

[来源]:Verify a certificate chain using openssl verify或者在这里查看一个非常好的博客:- https://mail.python.org/pipermail/cryptography-dev/2016-August/000676.html

注意: 如果您有 java keystore ,但没有 CA 提供的原始证书并已导入自定义 keystore ,请先使用 keytool 将 JKS 转换为 PKCS12,然后提取私钥证书。

keytool -importkeystore -srckeystore customeKeystore.jks -destkeystore customKeystore_pkcs.p12 -srcstoretype JKS - deststoretype PKCS12 

根据提示提供密码并避免在命令中传递密码

现在使用下面来提取证书。 openssl pkcs12 -in customKeystore_pkcs.p12 -nodes -out pvtkey_hostORdns_cert.pem 使用相同的 keytool 实用程序检查新生成的 PKCS12 keystore

keytool -list -v -keystore customKeystore_pkcs.p12 -storetype pkcs12

您也可以通过使用查看此文件

openssl x509 -inform PEM -in pvtkey_hostORdns_cert.pem -noout -text

关于java - 建立 SSL 主机连接时无法使用签名证书验证 Cacerts,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52641106/

上一篇:ssl - 使用新证书后 TLS 握手失败

下一篇:java - trustAnchors 参数必须是非空的

相关文章:

java - 如何使用 Apache HttpClient 4.3 处理 Cookie

java - 如何从 URL 查询字符串中读取 JSON 对象

java - 服务帐户抛出 - SSLHandshakeException

amazon-web-services - 在 EC2 和负载均衡器上安装 SSL

ssl - 尝试从 Twilio 接收 SMS,twilio 出现 SSL/TLS 握手错误

openssl - BIO_do_handshake() 总是返回 0

java - java.util.TreeSet的tailSet操作的时间复杂度是多少?

java - 如何将图像数据复制到 BufferedImage 的子类中?

linux - 从letsencrypt生成ssl时出错

asp.net-mvc-3 - SSL 证书将加密我的 MVC 3 应用程序中使用的查询字符串值