首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在使用Apache异步HttpClient 4.0.x时忽略HTTPS连接上的坏证书

在使用Apache异步HttpClient 4.0.x时忽略HTTPS连接上的坏证书
EN

Stack Overflow用户
提问于 2015-01-15 08:18:33
回答 2查看 5.8K关注 0票数 1

我使用异步Apache HttpClient (CloseableHttpAsyncClient)连接到服务器,但遇到以下异常:

代码语言:javascript
复制
javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at org.apache.http.concurrent.BasicFuture.failed(BasicFuture.java:130)
    at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.failed(DefaultClientExchangeHandlerImpl.java:258)
    at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.exception(HttpAsyncRequestExecutor.java:123)
    at org.apache.http.impl.nio.client.InternalIODispatch.onException(InternalIODispatch.java:68)
    at org.apache.http.impl.nio.client.InternalIODispatch.onException(InternalIODispatch.java:37)
    at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:124)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:159)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:338)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:316)
    at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:277)
    at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:105)
    at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:584)
    at java.lang.Thread.run(Thread.java:695)
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Handshaker.java:1015)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:485)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1108)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1080)
    at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:452)
    at org.apache.http.nio.reactor.ssl.SSLIOSession.doWrap(SSLIOSession.java:220)
    at org.apache.http.nio.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:254)
    at org.apache.http.nio.reactor.ssl.SSLIOSession.isAppInputReady(SSLIOSession.java:391)
    at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:119)
    ... 7 more
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1508)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:243)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1209)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:135)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
    at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Handshaker.java:533)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Handshaker.java:952)
    at org.apache.http.nio.reactor.ssl.SSLIOSession.doRunTask(SSLIOSession.java:238)
    at org.apache.http.nio.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:276)
    ... 9 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
    at sun.security.validator.Validator.validate(Validator.java:218)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1188)
    ... 16 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
    ... 22 more

因为这是一个测试服务器,我只想让CloseableHttpAsyncClient忽略所有的SSL错误。我知道如何使用HttpClient的非异步版本(例如,已经回答了这里 ),但我无法使用异步版本来实现这一点。

我试过以下几种方法:

代码语言:javascript
复制
TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
    public boolean isTrusted(X509Certificate[] certificate, String authType) {
        return true;
    }
};

SSLContext sslContext = null;
try {
    sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
} catch (Exception e) {
    // Handle error
}

CloseableHttpAsyncClient client = HttpAsyncClients.custom()
        .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
        .setSSLContext(sslContext).build();

但不起作用。有人知道怎么解决这个问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-16 18:34:18

实际上,我在问题中提供的代码起了作用。问题是,我使用的是尤内斯特 (它在引擎盖下使用Apache HttpClient ),并将其配置如下:

代码语言:javascript
复制
Unirest.setAsyncHttpClient(createHttpAsyncClient(CONNECTION_TIMEOUT, SOCKET_TIMEOUT));
Unirest.setTimeouts(CONNECTION_TIMEOUT, SOCKET_TIMEOUT);

问题是,"setTimeouts“忽略了我在createHttpAsyncClient中所做的配置,没有任何指示。变到

代码语言:javascript
复制
Unirest.setTimeouts(CONNECTION_TIMEOUT, SOCKET_TIMEOUT);
Unirest.setAsyncHttpClient(createHttpAsyncClient(CONNECTION_TIMEOUT, SOCKET_TIMEOUT));

让一切正常运转。

因此,如果其他人对纯异步Apache HTTPClient有相同的问题,那么使其信任所有证书的代码如下:

代码语言:javascript
复制
TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
    public boolean isTrusted(X509Certificate[] certificate, String authType) {
        return true;
    }
};

SSLContext sslContext = null;
try {
    sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
} catch (Exception e) {
    // Handle error
}

CloseableHttpAsyncClient client = HttpAsyncClients.custom()
        .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
        .setSSLContext(sslContext).build();
票数 5
EN

Stack Overflow用户

发布于 2015-01-15 09:53:49

我怀疑这个问题与主机名验证无关。在谈判SSL会话之前,SSL握手可能会在更早的时候失败。这种失败可能有各种原因,最有可能的是SSL协议版本错配。使用SSL调试日志(使用-Djavax.net.debug=all系统属性)运行应用程序,并分析日志输出。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27959164

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档