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

Java 忽略Apache HTTPClient 4.5中的自签名证书,java,ssl,httpclient,apache-httpclient-4.x,apache-commons-httpclient,Java,Ssl,Httpclient,Apache Httpclient 4.x,Apache Commons Httpclient,我正在尝试使用Apache HTTPClient 4.5版接受所有证书和/或接受自签名证书(教程链接) 我已经从一堆帖子中找到了这个问题的解决方案。到目前为止,他们都没有成功 我一直收到这个错误:在尝试执行请求时出错。javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接 Apache文档: 适用于版本3,但不适用于版本4 相关StackOverflow问题-以下是我尝试过的解决方案的一些链接: 请注意,在所有这些示例中,我还传递了

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

我已经从一堆帖子中找到了这个问题的解决方案。到目前为止,他们都没有成功

我一直收到这个错误:
在尝试执行请求时出错。javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接

Apache文档:

  • 适用于版本3,但不适用于版本4
相关StackOverflow问题-以下是我尝试过的解决方案的一些链接:

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

试试看 使用
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();
结果:不起作用。尝试执行请求时出现
错误。javax.net.ssl.SSLHandshakeException:握手期间远程主机关闭连接

试试看 与上面相同,但添加一个
poollighttpclientconnectionmanager

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:握手期间远程主机关闭连接

试试看 我从以下方面发现了一些有用的东西:

从版本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();
SSLContext SSLContext=SSLContexts.createSystemDefault();
SSLConnectionSocketFactory SSLConnectionSocketFactory=新SSLConnectionSocketFactory(
sslcontext,新字符串[]{“TLSv1”,“SSLv3”},null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
注册表socketFactoryRegistry=RegistryBuilder.create()
.register(“http”,PlainConnectionSocketFactory.INSTANCE)
.register(“https”,sslConnectionSocketFactory)
.build();
PoolightPClientConnectionManager cm=新的PoolightPClientConnectionManager(socketFactoryRegistry);
httpclient=HttpClients.custom()
.setDefaultCredentialsProvider(CredProvider)
.setDefaultCookieStore(cookieStore)
.setSSLSocketFactory(sslConnectionSocketFactory)
.setConnectionManager(cm)
.build();

结果:不起作用。尝试执行请求时出现
错误。javax.net.ssl.SSLHandshakeException:在握手过程中远程主机关闭连接

上述方法中的一种应该适用于自签名证书,但奇怪的是,在所有方法中都会出现相同的异常

我觉得在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");

这个问题与SSL连接有关。当您尝试连接到某些资源时,需要创建安全连接。这意味着只有您的浏览器和网站服务器知道请求体中发送的数据。这种安全性是通过ssl证书实现的,ssl证书存储在网站上,并在第一次连接到主机时由您的浏览器(或任何其他客户端,在本例中为Apache Http客户端)下载。有RSA256加密和许多其他很酷的东西。 但在一天结束时:如果证书未注册或无效,您将看到证书错误(HTTPS连接不安全)。 要修复证书错误,网站提供商需要为特定网站购买证书或以某种方式修复证书错误,例如

但是,当您使用跳过ssl验证时,会有一个旁路

(s, sslSession) -> true
这是安全违规,因为您不能100%确定数据是否安全,但是当使用测试数据和受信任的网站时,此解决方案可用于测试或配置

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();
        }

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

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();
}
private CloseableHttpClient newClient()抛出KeyManagementException、nosuchagorithmexception、KeyStoreException{
SSLContext context=SSLContexts.custom()
.loadTrustMaterial(TrustSelfSignedStrategy.INSTANCE)
.build();
Registry Registry=RegistryBuilder.create()
.register(“http”,PlainConnectionSocketFactory.INSTANCE)
.register(“https”,新的SSLConnectionSocketFactory(上下文,NoopHostnameVerifier.INSTANCE))
.build();
PoolightPClientConnectionManager connectionManager=新的PoolightPClientConnectionManager(注册表);
返回HttpClients.custom()
.setConnectionManager(connectionManager)
.build();
}

我使用的是ApacheHttpClient 4.5.3,上述解决方案都没有帮助。我总是犯错误

PKIX路径生成失败

我从中找到了解决办法

这是我的密码:

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();
}

是的,你说得对。我只是试着去实际的网站,我想这是下来lol他们可能一直在工作添加一些评论和描述。
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();
}