Java "sun.security.validator.ValidatorException: PKIX path building failed" 证书验证错误

Java "sun.security.validator.ValidatorException: PKIX path building failed" certificate validation error

我正在尝试通过 java 检索使用 SSL 证书的论坛的索引页:

WebClient webClient = new WebClient(...);
HtmlPage sectionPage = webClient.getPage("https://rstforums.com/");

我已经按照建议禁用了 SNI here programmatically prior to invoking any SSL related methods. Following the second answer to this question and the third from this 我将论坛的证书添加到证书列表中:

C:\Program Files\Java\jdk1.8.0_65\jre\lib\security>keytool -import -alias RST_CERT -file forums_certificate -keystore cacerts

其中 forums_certificate 包含:

-----BEGIN CERTIFICATE-----
MIIDmjCCAoKgAwIBAgIQLIJ9H3N2RZkAeZ8Jmma6RzANBgkqhkiG9w0BAQsFADBI
MRswGQYDVQQDExJFU0VUIFNTTCBGaWx0ZXIgQ0ExHDAaBgNVBAoTE0VTRVQsIHNw
b2wuIHMgci4gby4xCzAJBgNVBAYTAlNLMB4XDTE1MTEyNDEyNTI0MFoXDTE2MTEy
NDEyNTMyMlowWjELMAkGA1UEBhMCUk8xGjAYBgNVBAMTEXd3dy5yc3Rmb3J1bXMu
Y29tMS8wLQYJKoZIhvcNAQkBFiByc3Rmb3J1bXMuY29tQGRvbWFpbnNieXByb3h5
LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK9jSCt9p+g3wdP9
KhmNQuB5NZMlDoL0A5ONzUat5RPf1iQ91+1EWfS1j93X6m5mMSs5+RMc259TjMPv
oxSq9lK7Z0ZwUdHPkjVmMDKOOlho2zh1ZTh7W26dT8UmeuofgFCxaJBuThalWkpg
qT5GgpcuIXWQVlB4vD43/wdPhWFUZ1QhFgK/HppiXVfKNbBRNM69iSbjzkBbstXI
68yLxtbzwOqEdIpJ5CWxQCr0+BCk7SPGHyXbJaVL1SuQ/7Th8PkJd43bBTLsVY5w
WemSZfEoqeCeHUxeMSdMy1FKkUBTlvZBn+KBVUAJ419rE+Jgrp4tikwjJxEjB/Ko
Uwdkb9ECAwEAAaNuMGwwCQYDVR0TBAIwADATBgNVHSUEDDAKBggrBgEFBQcDATAd
BgNVHQ4EFgQU9+VnJO4u71+3bAS9hYFiXtzG+FswKwYDVR0RBCQwIoIRd3d3LnJz
dGZvcnVtcy5jb22CDXJzdGZvcnVtcy5jb20wDQYJKoZIhvcNAQELBQADggEBAHxq
icR/mSh0TTQlb6SreCyxNyO4KflAOnp3yFnFStVo7wxI5Ixb2jCUP/IGxSwJeN2p
AEzAWXls9NoMVcEIbIfGcdsvJS1yyh6GeWVzBrMNOde1/2590ipsPKyQAk2j1zPl
96kWnPWTB6DtSbB3AI4dWeawwkh2D5+NL5HMjQwm3Lb3EhKQgBPLboygg12E+JXP
ydZjIZWC/42nN5ZMHXXrGnxac5F3tMwkyng0qDWLpSoa3c3ep43Tgwo08RFuZzuV
7hvvG006M4QMQj/nbQXzhbjko3cRVegvV9xKnNxe5oCArTK5HNkfPhEM/G48ed4h
z99OS5+RiB/NLTfzlPc=
-----END CERTIFICATE-----

证书已成功添加并在列出其条目时出现在密钥库中:

rst_cert, Feb 3, 2016, trustedCertEntry, 
Certificate fingerprint (SHA1): 25:39:98:FC:FF:DE:2D:24:BC:F0:78:93:D6:2E:5A:55:64:D5:09:8A

当我尝试重新运行发出新请求的应用程序时,出现了同样的错误:

sun.security.validator.ValidatorException: PKIX path building failed: sun.securi
ty.provider.certpath.SunCertPathBuilderException: unable to find valid certifica
tion path to requested target
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.jav
a:292)
        at sun.security.validator.Validator.validate(Validator.java:260)
        at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.j
ava:324)
        at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerIm
pl.java:229)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustMan
agerImpl.java:124)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.
java:1491)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.jav
a:216)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.
java:1375)
        at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:747)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
        at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:138)
        at SSLPoke.main(SSLPoke.java:31)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to
 find valid certification path to requested target
        at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBu
ilder.java:146)
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCert
PathBuilder.java:131)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382)
        ... 15 more

我有建议 here(已下载 SSLPoke),但错误仍然存​​在。为什么证书不被识别?

我已经设法使用 openssl(来自 cygwin(我正在使用 Win7))删除证书并将其添加到密钥库。

要使用 openssl 检索证书:

openssl x509 -in <(openssl s_client -connect rstforums.com:443 -prexit 2>/dev/null) -out ~/rst_cert.crt

要从商店中删除当前 rst_cert

keytool -delete -alias rst_cert -keystore cacerts

添加使用openssl下载的证书:

keytool -importcert -file ~/example.crt -alias example -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit

使用 firefox 下载的证书显然无效。

对于本地主机开发者, 经过数小时的操作,例如向 cacert 添加证书、生成 jks 文件、使用 InstallCert.java...这是解决方案,忽略证书,覆盖 TrustManager,效果很好:

http://www.rgagnon.com/javadetails/java-fix-certificate-problem-in-HTTPS.html