使用抛出 ValidatorException 的 Apache Commons HttpClient 3.1 连接到 Java 中的安全服务器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1623924/
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
Connecting to Secure Server in Java using Apache Commons HttpClient 3.1 throwing ValidatorException
提问by Kryten
I am trying to connect to a secure server using Apache Commons HttpClient 3.1.
The problem is everytime the application connects it throws a
我正在尝试使用Apache Commons HttpClient 3.1.
问题是每次应用程序连接时都会抛出一个
sun.security.validator.ValidatorException.
sun.security.validator.ValidatorException。
Here is the stacktrace:
这是堆栈跟踪:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: subject/issuer name chaining check failed javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: subject/issuer name chaining check failed at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1611) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:181) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1035) at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:124) at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516) at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1112) at 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) at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114) at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096) at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398) at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) at balanceschecker.connector.Connector.conn(Connector.java:27) at balanceschecker.connector.Connector.RawPost(Connector.java:99) at balanceschecker.connector.Connector.Post(Connector.java:111) at balanceschecker.login.Login.Login(Login.java:87) at balanceschecker.Main.main(Main.java:21) Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: 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) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1014) ... 21 more Caused by: java.security.cert.CertPathValidatorException: subject/issuer name chaining check failed at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:139) at sun.security.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:326) at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:178) at java.security.cert.CertPathValidator.validate(CertPathValidator.java:250) at sun.security.validator.PKIXValidator.doValidate(PKIXValidator.java:246) ... 28 more
javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径验证失败:java.security.cert.CertPathValidatorException:主题/颁发者名称链接检查失败 javax.net.ssl.SSLHandshakeException:sun.security.validator。 ValidatorException:PKIX 路径验证失败:java.security.cert.CertPathValidatorException:com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174) 处的主题/颁发者名称链接检查失败。 net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1611) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:187) at com.sun.net.ssl。 internal.ssl.Handshaker.fatalSE(Handshaker.java:181) 在 com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1035) 在 com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:124) 在 com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:516) 在 com .sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:454) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884) at com.sun.net .ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1112) 在 com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:623) 在 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。org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114) 上的 httpclient.methods.EntityEnclosureMethod.writeRequestBody(EntityEnclosureMethod.java:506) org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java: 1096) 在 org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398) 在 org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) 在 org.apache.commons.httpclient.HttpClient .executeMethod(HttpClient.java:397) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) at balanceschecker.connector.Connector.conn(Connector.java:27) at balanceschecker.connector.Connector。 RawPost(Connector.java:99) at balanceschecker.connector。Connector.Post(Connector.java:111) at balanceschecker.login.Login.Login(Login.java:87) at balanceschecker.Main.main(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) 在 sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:158) 在 sun.security.validator.Validator.validate(Validator.java:218) 在 com.sun.net.ssl.internal.ssl。 X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126) 在 com.sun.net.ssl.internal.ssl.X509TrustManagerImpl。checkServerTrusted(X509TrustManagerImpl.java:209) 在 com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249) 在 com.sun.net.ssl.internal.ssl.ClientHandshaker(ClientHandshaker) java:1014) ... 21 更多 引起:java.security.cert.CertPathValidatorException:主题/发行者名称链接检查在 sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(PKIXMasterCertPathValidator.java:139) at sun.security 失败.provider.certpath.PKIXCertPathValidator.doValidate(PKIXCertPathValidator.java:326) 在 sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(PKIXCertPathValidator.java:178) 在 java.security.cert.CertPathValidator.validate(CertPathValidator.java:2500) ) 在 sun.security.validator。PKIXValidator.doValidate(PKIXValidator.java:246) ... 28 更多
Heres the code I am using (edited and compacted a bit)
这是我正在使用的代码(稍微编辑和压缩)
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();
}
I had a look at the site's certificates and they are still valid for over a year. I then tried to bypass the certificate check using the code shown in "How to bypass trusted host and certificate check in Java", however the exception is still thrown.
我查看了该网站的证书,它们的有效期仍然超过一年。然后,我尝试使用“如何绕过 Java 中的可信主机和证书检查”中显示的代码绕过证书检查,但是仍然抛出异常。
What am I doing wrong?
How can I connect successfully to the server?
我究竟做错了什么?
我怎样才能成功连接到服务器?
回答by ZZ Coder
This error means it can't validate the certificate chain. Possible causes are,
此错误意味着它无法验证证书链。可能的原因是,
- The root CA is not trusted by your JRE.
- The certificate is signed by an intermediate cert but server is not sending it along with the cert.
- 您的 JRE 不信任根 CA。
- 证书由中间证书签名,但服务器不会将其与证书一起发送。
Here is how get a list of root cert,
这是获取根证书列表的方法,
keytool -list -keystore $JAVA_HOME/lib/security/cacerts -v
I don't know any Java way to check if intermediate cert is sent. I use openssl for that,
我不知道任何 Java 方法来检查是否发送了中间证书。我为此使用了 openssl,
openssl s_client -host example.com -port 443
Will show you all the certificate sent by server. Pay attention to "Certificate chain".
将向您显示服务器发送的所有证书。注意“证书链”。

