忽略 Apache HTTPClient 4.5 中的自签名证书

新手上路,请多包涵

我正在尝试 接受所有证书,和/或接受 使用 Apache HTTPClient 4.5 版 的自签名证书( 此处 为教程链接)

我一直在通过关于 SO 的一堆帖子来解决这个问题。到目前为止,他们都没有工作。

我不断收到此错误: Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

阿帕奇文档:

相关 StackOverflow 问题- 以下是我尝试过的解决方案的一些链接:

请注意,在所有这些示例中,我还传递了一个 cookie 存储和一个我之前定义的代理凭据提供程序。这些都在工作,我只是想添加 SSL 支持。

尝试#1

使用 --- 创建我自己的 ssl 上下文,并使用 TrustSelfSignedStrategy SSLContextBuilder 信任所有自签名策略。

 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

我从 这个答案 中发现了一些有用的东西:

从 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

原文由 Katie 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

上述方法之一应该适用于自签名证书,但奇怪的是您在所有方法中都遇到相同的异常。

我觉得在 SSL 会话建立期间或握手协议没有被客户端或服务器接受。

这里最好的解决方案是调试应用程序。

如果是 tomcat,请在 setenv.sh 或 setenv.bat 文件中添加 -Djavax.net.debug=all ,然后重新启动服务器。

或者您可以按照 本教程 进行操作。

OP 只需要在连接到 SSL 时更改端口:

 //For HTTPS
HttpHost httpstarget = new HttpHost("mysite.com", 443, "https");

//For HTTP
HttpHost httptarget = new HttpHost("mysite.com", 80, "http");

原文由 Azim 发布,翻译遵循 CC BY-SA 4.0 许可协议

我正在使用 Apache HttpClient 4.5.3,但上述解决方案均无济于事。我总是得到错误

PKIX 路径构建失败

.

我在 http://www.baeldung.com/httpclient-ssl 中找到了解决方案

这是我的代码:

 try {
    SSLContext sslContext = new SSLContextBuilder()
            .loadTrustMaterial(null, (certificate, authType) -> true).build();
    httpClient = HttpClients.custom().setSSLContext(sslContext)
            .setSSLHostnameVerifier(new NoopHostnameVerifier())
            .build();
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
    e.printStackTrace();
}

原文由 Martin Pabst 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题