我正在尝试使用URLConnection(java.net)和Apache的HTTPClient.
在这两种情况下,当我发出请求时,我得到以下异常:
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException:
PKIX path validation Failed:
java.security.cert.CertPathValidatorException:
basic constraints check Failed:
pathLenConstraint violated – this cert
must be the last cert in the
certification path at
com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1518)
at
com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)
at
com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)
at
com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:848)
at
com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)
at
com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)
at
com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:818)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1030)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1057)
at
com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1041)
at
sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:402)
at
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:934)
at
sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
at
com.sap.river.coghead.rest.Main.testJavaHTTPConnection(Main.java:45)
at
com.sap.river.coghead.rest.Main.main(Main.java:32)
Caused by:
sun.security.validator.ValidatorException:
PKIX path validation Failed:
java.security.cert.CertPathValidatorException:
basic constraints check Failed:
pathLenConstraint violated – this cert
must be the last cert in the
certification path at
sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:187)
at
sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:139)
at
sun.security.validator.Validator.validate(Validator.java:203)
at
com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)
at
com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)
at
com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841)
… 13 more Caused by:
java.security.cert.CertPathValidatorException:
basic constraints check Failed:
pathLenConstraint violated – this cert
must be the last cert in the
certification path at
sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:139)
at
sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:316)
at
sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:178)
at
java.security.cert.CertPathValidator.validate(CertPathValidator.java:206)
at
sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:182)
… 18 more
请注意,我已经成功地建立了非ssl连接,但是不同的主机.
我也可以使用浏览器查看此页面 – 证书在那里正确验证.
我是否需要以某种方式更改证书的顺序,因为它们是从服务器检索的?
是否有一些我缺少的配置?
提前致谢,
利奥尔
解决方法
密钥存储区是jre中用于运行程序的jre / lib / security文件夹下的“cacerts”文件.
我手动导出了网站的证书 – 所有这些证书.
然后我使用Sun提供的’keytool’实用程序将其导入我的默认密钥库.请注意,您必须以正确的顺序导入它们.
然后我把新的密钥库而不是JRE的密钥库 – 它起作用了.
我想将证书直接导入JRE的密钥库会更好,但该工具要求我输入一个我不知道的密码.
我相信还有一种方法可以更轻松地对此进行编程,但还没有找到它.我很乐意得到一些指针(JSSE中的TrustManager类?).
最后,一些功劳.这篇帖子:http://javaishdiscoveries.blogspot.com/2009/02/battle-with-cacerts-and-https.html帮我指出了正确的方向.