首页 文章

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

提问于
浏览
9

我正在尝试 accept all certificates, and/or accept self-signed certificates 使用 Apache HTTPClient version 4.5 (教程链接here

我已经从SO上的一堆帖子中解决了这个问题 . 到目前为止,他们都没有工作过 .

我一直收到这个错误: Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

Apache Docs:

Related StackOverflow Questions - 这里's some links of the solutions I'尝试过:

请注意,在所有这些示例中,我还传递了我之前定义的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();

RESULT :没用 . 得到 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();

RESULT :没用 . 得到 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();

RESULT :没用 . 得到 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();

RESULT :没用 . 得到 Error while trying to execute request. javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

4 回答

  • 7

    上述方法之一应该适用于自签名证书,但奇怪的是你在所有方法中都得到了同样的例外 .

    我觉得在SSL会话 Build 或握手协议期间,客户端或服务器都没有接受 .

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

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

    或者你可以关注this tutorial .

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

    //For HTTPS
    HttpHost httpstarget = new HttpHost("mysite.com", 443, "https");
    
    //For HTTP
    HttpHost httptarget = new HttpHost("mysite.com", 80, "http");
    
  • 2

    我使用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();
    }
    
  • 4

    通常,您不仅需要支持自签名证书,还需要调用多线程请求,因此请使用池连接管理器 . 我是这样做的:

    private CloseableHttpClient newClient() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
        SSLContext context = SSLContexts.custom()
                .loadTrustMaterial(TrustSelfSignedStrategy.INSTANCE)
                .build();
    
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create()
                .register("http", PlainConnectionSocketFactory.INSTANCE)
                .register("https", new SSLConnectionSocketFactory(context, NoopHostnameVerifier.INSTANCE))
                .build();
    
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
    
        return HttpClients.custom()
                .setConnectionManager(connectionManager)
                .build();
    }
    
  • 2
    public static HttpClient newClient() {
            SSLContext sslcontext = null;
            try {
                sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
            } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
                e.printStackTrace();
            }
    
            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslcontext,
                    (s, sslSession) -> true);
    
            return HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory)
                    .build();
        }
    

相关问题