问题描述
我正在尝试使用 Apache HTTPClient 4.5版 接受所有证书和/或接受自签名证书(教程链接)
I am trying to accept all certificates, and/or accept self-signed certificates using Apache HTTPClient version 4.5 (tutorial link here)
我'已经从SO上的一堆帖子中解决了这个问题。到目前为止,他们都没有工作过。
I've been going through solutions to this problem from a bunch of posts on SO. So far none of them have worked.
我一直收到此错误: 尝试执行请求时出错。 javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接
I keep getting this error: Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
Apache Docs:
Apache Docs:
- ,但不是版本4.
- Apache v4.5 tutorial
- SSL/TLS customization
- Apache has a guide for version 3, but not version 4.
相关StackOverflow问题 - 以下是我尝试过的解决方案的一些链接:
Related StackOverflow Questions - Here's some links of the solutions I've tried:
- 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支持。
Note that in all these examples I am also passing a cookie store and a proxy credentials provider that I defined earlier. These are working, I'm just trying to add SSL support.
创建我自己的带有 SSLContextBuilder
的ssl上下文,并信任所有使用 TrustSelfSignedStrategy
的自签名策略。
Create my own ssl context with SSLContextBuilder
and trust all self signed strategies with 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();
结果:没有用。得到尝试执行请求时出错。 javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接
与上述相同,但添加 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();
结果:没有用。得到尝试执行请求时出错。 javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接
通过覆盖 TrustStrategy
简单接受所有证书(不建议这样做)
Simply accept ALL certificates by overriding the TrustStrategy
(this is not recommended)
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();
结果:没有用。得到尝试执行请求时出错。 javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接
我在中找到了有用的内容:
I found something useful from this answer:
这是他的解决方案给出:
Here's the solution he gave:
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();
结果:没有用。得到尝试执行请求时出错。 javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接
推荐答案
以上之一在自签名证书的情况下,方法应该有效,但奇怪的是你在所有方法中都得到相同的异常。
One of the above approaches should work in case of self-signed certificates, but the weird thing is you are getting same exception in all the approaches.
我在SSL会话建立或握手协议中感觉到客户端或服务器不接受。
I feel during SSL session establishment or handshaking protocol is not being accepted either by client or by server.
这里最好的解决方案是调试应用程序。
The best solution here is to debug the application.
如果是tomcat,添加 - setenv.sh或setenv.bat文件中的Djavax.net.debug = all ,然后重新启动服务器。
In case of tomcat, add -Djavax.net.debug=all in setenv.sh or setenv.bat files and then restart the server.
或者你可以关注。
当连接到SSL时,OP只需更改端口:
The OP just needed to change the port when connecting to SSL:
//For HTTPS
HttpHost httpstarget = new HttpHost("mysite.com", 443, "https");
//For HTTP
HttpHost httptarget = new HttpHost("mysite.com", 80, "http");
这篇关于忽略Apache HTTPClient 4.5中的自签名证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!