Java“sun.security.validator.ValidatorException:PKIX路径构建失败”证书验证错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35185146/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:24:43  来源:igfitidea点击:

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

javavalidationsslcertificatessl-certificate

提问by Sebi

I'm trying to retrieve the index page of a forum that uses SSL certificates using java:

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

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

I've disabled SNI as recommended hereprogrammatically prior to invoking any SSL related methods. Following the second answer to thisquestion and the third from thisone I added the forum's certificate to the certificate list:

在调用任何与 SSL 相关的方法之前,我已经按照此处的建议以编程方式禁用了 SNI 。在第二次回答这个问题,并从第三一个我加入了论坛的证书,证书列表:

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

where forums_certificatecontains:

其中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+FswKwYDVR0RBCQwItheitroadd3d3LnJz
dGZvcnVtcy5jb22CDXJzdGZvcnVtcy5jb20wDQYJKoZIhvcNAQELBQADggEBAHxq
icR/mSh0TTQlb6SreCyxNyO4KflAOnp3yFnFStVo7wxI5Ixb2jCUP/IGxSwJeN2p
AEzAWXls9NoMVcEIbIfGcdsvJS1yyh6GeWVzBrMNOde1/2590ipsPKyQAk2j1zPl
96kWnPWTB6DtSbB3AI4dWeawwkh2D5+NL5HMjQwm3Lb3EhKQgBPLboygg12E+JXP
ydZjIZWC/42nN5ZMHXXrGnxac5F3tMwkyng0qDWLpSoa3c3ep43Tgwo08RFuZzuV
7hvvG006M4QMQj/nbQXzhbjko3cRVegvV9xKnNxe5oCArTK5HNkfPhEM/G48ed4h
z99OS5+RiB/NLTfzlPc=
-----END CERTIFICATE-----

The certificate has been successfully added and appears in the keystore when listing its entries:

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

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

When I try to rerun the application making a new request, the same error is given:

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

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

I have the suggestions here(downloaded SSLPoke) but the error persists. Why isn't the certificate recognized?

我在这里有建议(下载 SSLPoke),但错误仍然存​​在。为什么证书不被认可?

采纳答案by Sebi

I've managed to remove and add the certificate to the keystore using openssl (from cygwin (I am working on Win7)).

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

To retrieve the certificate using openssl:

使用 openssl 检索证书:

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

To remove the current rst_certfrom the store:

要从rst_cert商店中删除当前:

keytool -delete -alias rst_cert -keystore cacerts

To add the certificate downloaded using openssl:

添加使用 openssl 下载的证书:

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

The certificate downloaded using firefox was apparently invalid.

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

回答by Indrek Ruubel

For localhost developers, After hours of doing things like adding certificates to cacert, generating jks files, using InstallCert.java... Here is the solution, ignore the certificate, override the TrustManager, works like a charm:

对于本地主机开发人员,经过数小时的工作,例如将证书添加到 cacert,生成 jks 文件,使用 InstallCert.java...这是解决方案,忽略证书,覆盖 TrustManager,就像一个魅力:

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

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