我正在尝试使用连接到安全服务器Apache Commons HttpClient 3.1
.
问题是每次应用程序连接它抛出一个
sun.security.validator.ValidatorException.
这是堆栈跟踪:
javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径验证失败:java.security.cert.CertPathValidatorException:subject/issuer name chaining check failed javax.net.ssl.SSLHandshakeException:sun.security.validator. ValidatorException:PKIX路径验证失败:java.security.cert.CertPathValidatorException:主题/发布者名称链接检查在com.sun的com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)失败. net.sssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1611)位于com.sun.net.ssl的com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187). internal.sssl.Handshaker.fatalSE(Handshaker.java:181)位于com.sun.net.ssl.internal.ssl的com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1035). ClientSandshaker.processMessage(ClientHandshaker.java:124)at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516)at com.sun.net.ssl.internal.ssl.Handshaker.proces s_record(Handshaker.java:454)位于com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)的com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl. java:1112)com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623)at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:506) )org.apache.com上的org.apache.com.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)org.apache.com上的httpMethodBase.exe执行(HttpMethodBase.java:1096)org.apache.commons.httpclient.HttpMethodDirector.执行org.apache.co的org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)中的executeWithRetry(HttpMethodDirector.java:398)mms.httpclient.HttpClient.executeMethod(HttpClient.java:397)atg.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)at balanceschecker.connector.Connector.conn(Connector.java:27)at balanceschecker位于balanceschecker.Main.main的balanceschecker.login.Login.Login(Login.java:87)处于balanceschecker.connector.Connector.Post(Connector.java:111)的.connector.Connector.RawPost(Connector.java:99) Main.java:21)引起:sun.security.validator.ValidatorException:PKIX路径验证失败:java.security.cert.CertPathValidatorException:subject/issuer name chaining check failed at sun.security.validator.PKIXValidator.doValidate(PKIXValidator. java:251)at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:234)at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:158)at sun.security.validator.Validator.validate(Validator) .java:218)在com.sun的com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126).net.sssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)位于com.sun.net.ssl的com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249). internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1014)... 21更多引起:java.security.cert.CertPathValidatorException:subject/issuer name chaining check failed at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate( PKIXMasterCertPathValidator.java:139)位于sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:326),位于java.security.cert的sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:178) .certPathValidator.validate(CertPathValidator.java:250)at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:246)... 28更多
下面是我正在使用的代码(编辑和压缩了一下)
installAllTrustManager(); PostMethod post = new PostMethod(server_path); NameValuePair[] data = new NameValuePair { new NameValuePair("Username", username), new NameValuePair("Password", password) }; post.setRequestBody(data); post.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(3, false)); try { HttpClient hc = new HttpClient(); int result2 = hc.executeMethod(post); if (result2 != HttpStatus.SC_OK) { throw new IOException("HTTP Status Not OK: " + result2); } return post.getResponseBodyAsStream(); } finally { post.releaseConnection(); }
我看了一下网站的证书,它们仍然有效一年多了.然后,我尝试使用" 如何绕过Java中的可信主机和证书检查 "中显示的代码绕过证书检查,但仍然抛出异常.
我究竟做错了什么?
如何成功连接到服务器?
此错误意味着它无法验证证书链.可能的原因是,
您的JRE不信任根CA.
证书由中间证书签名,但服务器不与证书一起发送.
以下是如何获取根证书列表,
keytool -list -keystore $JAVA_HOME/lib/security/cacerts -v
我不知道任何Java方法来检查是否发送了中间证书.我使用openssl,
openssl s_client -host example.com -port 443
将显示服务器发送的所有证书.注意"证书链".