使用Apache Httpclient和WebSphere Liberty Profile设置TLS版本

时间:2016-04-21 16:41:17

标签: apache-httpclient-4.x websphere-liberty tls1.2

我们正在从WebSphere Liberty Profile(8.5.5.6)REST服务访问外部服务,该服务使用Apache HTTPClient 4.3.5连接到服务。

该服务刚刚更改为使用TLS v1.2,现在我们的服务失败了: [4/21/16 12:23:37:596 EDT] 0000005d bm.myw3.services.awf.sso.ejb.generator.SSOTokenGeneratorImpl I Exception :: javax.net.ssl.SSLException:收到致命警报:protocol_version [4/21/16 12:23:37:597 EDT] 0000005d com.ibm.myw3.services.awf.sso.ejb.SSOTokenManagerBean E SSOTokenGeneratorException :: {0} com.ibm.myw3.services.awf.sso.ejb.config.SSOTokenGeneratorException:执行用于检索令牌的http请求时发生异常

我们找到了以下链接,并在我们的代码中实现了它:
How to set TLS version on apache HttpClient

SSLContext sslContext = SSLContexts.custom().useTLS().build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" }, null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

我还设置了' https.protocols':

wasadmin 28548 1 10 12:28 pts / 0 00:00:55 /usr/lib/jvm/jre-1.7.1-ibm.x86_64/bin/java -javaagent:/ opt / IBM / WebSphere / Liberty / wlp / bin / tools / ws-javaagent.jar -Djava.awt.headless = true -XX:MaxPermSize = 256m -Dcom.ibm.security.jurisdictionPolicyDir = / devops / w3Services / ssoProxy -Dhttps.protocols = TLSv1.2,TLSv1 .1,TLSv1 -jar /opt/IBM/WebSphere/Liberty/wlp/bin/tools/ws-server.jar w3svcs-ssoproxy-svr1

但它没有任何区别。为了让这个与WLP协同工作,我们还需要做些什么吗?

2 个答案:

答案 0 :(得分:0)

我们已经尝试了其他一些东西,这是我们最新的代码迭代:

SSLContext sslContext = SSLContexts.custom().useProtocol("TLSv1.2").build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" },
    new String[] { "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
    SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig)
    .setConnectionManager(connManager).setSSLSocketFactory(sslsf);
handleAuthentication(uri, httpClientBuilder);
httpClient = httpClientBuilder.build();

我还设置了以下JVM选项:
JVM_ARGS = -Dhttps.protocols = TLSv1.2 -Djdk.tls.client.protocols = TLSv1.2 -Djavax.net.debug = all

但我们仍然收到错误:

[4/21/16 17:27:37:123 EDT] 00000042 id = bm.myw3.services.awf.sso.ejb.generator.SSOTokenGeneratorImpl I Exception :: javax.net.ssl.SSLException:收到致命信号alert:protocol_version
[4/21/16 17:27:37:124 EDT] 00000042 id = com.ibm.myw3.services.awf.sso.ejb.SSOTokenManagerBean E SSOTokenGeneratorException :: {0} com.ibm.myw3.services.awf.sso.ejb.config.SSOTokenGeneratorException:执行用于检索令牌的http请求时发生异常

我有一个来自WLP的trace.log,如果有人认为它有用,我可以上传。但是这里有来自跟踪的各种条目:

Default Executor-thread-25, WRITE: TLSv1.2 Handshake, length = 80
Default Executor-thread-25, WRITE: TLSv1.2 Application Data, length = 256
Default Executor-thread-25, READ: TLSv1.2 Application Data, length = 1552
SEND TLSv1.2 ALERT:
Finalizer thread, WRITE: TLSv1.2 Alert, length = 64

然后继续尝试TLSv1,我们所调用的服务不再支持了。我不知道该找什么来确定它为什么没有使用TLSv1.2,但没有任何东西从追踪中跳出来。

答案 1 :(得分:0)

在构建HttpClient实例时,无法同时设置自定义套接字工厂和完全初始化的连接管理器。方法#setConnectionManager取代#setSSLSocketFactory。

做这个

SSLContext sslContext = SSLContexts.custom().useProtocol("TLSv1.2").build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" },
        new String[] { "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
        SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
        .setDefaultRequestConfig(requestConfig)
        .setSSLSocketFactory(sslsf);

或者

SSLContext sslContext = SSLContexts.custom().useProtocol("TLSv1.2").build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" },
        new String[] { "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" },
        SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
        .register("http", PlainConnectionSocketFactory.getSocketFactory())
        .register("https", sslsf)
        .build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);

HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
        .setDefaultRequestConfig(requestConfig)
        .setConnectionManager(cm);

哦,是的,还有一件事。请考虑升级到4.5