【发布时间】:2017-02-16 18:37:29
【问题描述】:
我正在尝试使用 Apache HTTPClient 4.5 版接受所有证书和/或接受自签名证书(教程链接here)
我一直在通过 SO 上的一堆帖子解决这个问题。到目前为止,它们都没有奏效。
我不断收到此错误:Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
Apache 文档:
- Apache v4.5 tutorial
- SSL/TLS customization
- Apache has a guide 适用于第 3 版,但不适用于第 4 版。
StackOverflow 相关问题 - 以下是我尝试过的解决方案的一些链接:
- Ignoring SSL certificate in Apache HttpClient 4.3
- How to ignore SSL certificate errors in Apache HttpClient 4.0
- Ignore SSL Certificate Errors with Java
- Need to trust all the certificates during the development using Spring
- How to handle invalid SSL certificates with Apache HttpClient?
请注意,在所有这些示例中,我还传递了我之前定义的 cookie 存储和代理凭据提供程序。这些都在工作,我只是想添加 SSL 支持。
尝试#1
使用 SSLContextBuilder 创建我自己的 ssl 上下文,并使用 TrustSelfSignedStrategy 信任所有自签名策略。
SSLContextBuilder sshbuilder = new SSLContextBuilder();
sshbuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sshbuilder.build());
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.setDefaultCookieStore(cookieStore)
.setSSLSocketFactory(sslsf)
.build();
结果:没用。收到Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
尝试#2
同上,但添加PoolingHttpClientConnectionManager
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(),SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", new PlainConnectionSocketFactory())
.register("https", sslsf)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(2000);//max connection
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.setDefaultCookieStore(cookieStore)
.setSSLSocketFactory(sslsf)
.setConnectionManager(cm)
.build();
结果:没用。收到Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
尝试#3
只需通过覆盖TrustStrategy 来接受所有证书(不建议这样做)
SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
});
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(),
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.setDefaultCookieStore(cookieStore)
.setSSLSocketFactory(sslsf)
.build();
结果:没用。得到Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
尝试#4
我从this answer 发现了一些有用的东西:
从 4.5 版开始,HttpClient 通过以下方式禁用 SSLv3 协议版本 默认
这是他给出的解决方案:
SSLContext sslcontext = SSLContexts.createSystemDefault();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
sslcontext, new String[] { "TLSv1", "SSLv3" }, null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", sslConnectionSocketFactory)
.build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.setDefaultCookieStore(cookieStore)
.setSSLSocketFactory(sslConnectionSocketFactory)
.setConnectionManager(cm)
.build();
结果:没用。收到Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
【问题讨论】:
标签: java ssl httpclient apache-httpclient-4.x apache-commons-httpclient