使用 Java 的 WebSphere SSL 握手错误

SSL Handshake Error with WebSphere using Java

将 Java HTTP 客户端代码与 WebSphere 服务器 URL 连接时遇到错误。测试抛出 SSL 握手错误信息:

代码部署已通过 Java7 和 Java8 测试:

java -Djavax.net.ssl.keyStore=mykey.jks  -Djdk.tls.client.protocols=TLSv1.2 -Djavax.net.debug=ssl,handshake postHTTPWAS

日志文件:

.. 
jdk.tls.client.protocols is defined as TLSv1.2
SSLv3 protocol was requested but was not enabled
.. Extension server_name, server_name: [type=host_name (0), value=myhost.domain.com]
***
main, WRITE: TLSv1 Handshake, length = 155
main, received EOFException: error
main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
main, SEND TLSv1.2 ALERT:  fatal, description = handshake_failure
main, WRITE: TLSv1.2 Alert, length = 2
main, called closeSocket()
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

JRE的java.security设置配置如下:

...
jdk.jar.disabledAlgorithms=MD2, RSA keySize < 1024
jdk.tls.disabledAlgorithms=SSLv3
jdk.certpath.disabledAlgorithms=SSLv3
com.ibm.jsse2.disableSSLv3=true

问题:

1) 为什么 SSL 跟踪显示对 SSLv3 的引用,这是一种在客户端安全设置中逻辑上被禁用的协议?

2) SSLHandshakeException 的根本错误是什么?

3) 是否可以启用 TLSv1.2 作为所有 HTTPS 客户端连接的默认选择,哪个系统 属性 可以设置它?

我已经找出错误。

较新版本的 WAS 应用程序服务器(完整版)预计客户端将与 TLSv1.2 连接。对于手动 Java JRE 调用,使用参数 -Dhttps.protocols=TLSv1.2,如下所示:

/opt/java8/ibm-java-x86_64-80/bin/javac SSLTest.java && /opt/java8/ibm-java-x86_64-80/jre/bin/java -Dhttps.protocols=TLSv1.2  SSLTest

对于 Apache HTTPS 客户端 (> V.4.5.2),我添加了一些额外的部分,以使 HTTPS 与 TLSv1.2 连接。现在两个连接都工作正常。

// for TLSv1.2 add: 
import org.apache.http.config.Registry; 
import org.apache.http.config.RegistryBuilder; 
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import javax.net.ssl.SSLContext;
import java.security.NoSuchAlgorithmException;
import java.security.KeyManagementException; 
import org.apache.http.ssl.SSLContexts;  

    //Set the https use TLSv1.2
    private static Registry<ConnectionSocketFactory> getRegistry() throws KeyManagementException, NoSuchAlgorithmException {
        SSLContext sslContext = SSLContexts.custom().build();
        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
                new String[]{"TLSv1.2"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        return RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", PlainConnectionSocketFactory.getSocketFactory())
            .register("https", sslConnectionSocketFactory)
            .build();
    }

   // for TLSv1.2 use:  
   PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager(getRegistry());
   clientConnectionManager.setMaxTotal(100);
   clientConnectionManager.setDefaultMaxPerRoute(20);
   HttpClient client = HttpClients.custom().setConnectionManager(clientConnectionManager).build();