Java 7的javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake异常分析

Java7通过httpsURLConnection建立HTTPS连接,异常如下:

javax.net.ssl.SSLHandshakeException: Caused by: Remote host closed connection during handshake Caused by: SSL peer shut down incorrectly

解决方案似乎是明显的,客户端需要提高版本到TLSv1.1或TLSv1.2。这可以有2种实现思路,一种是设置JVM的https.protocols参数,另一种是构造支持TLSv1.1或TLSv1.2的SSLContext。

1) 通过-D给出JVM启动参数

-Dhttps.protocols=TLSv1.1,TLSv1.2

2) 必要时,在代码中设置运行时参数

System.setProperty("https.protocols", "TLSv1.1,TLSv1.2");

3) 构造支持TLSv1.1或TLSv1.2的SSLContext

SSLContext sslContext = SSLContext.getInstance("TLSv1.1");

SSLContext sslContext = SSLContext.getInstance("TLSv1.2");

其中的机理如下:

客户端Java 7默认使用Sun JSSE provider(PKCS12, SunX509 key/trust factories, SSLv3, TLSv1),支持SSLv3或TLSv1,默认通过TLSv1建立到服务器的HTTPS连接。被连接的服务器却只允许使用TLSv1.1或TLSv1.2的HTTPS连接请求。

Java 7经过多次小版本的更新,虽然Sun JSSE provider默认仍然使用TLSv1,但是也支持TLSv1.1或TLSv1.2。

补充:Sun JSSE provider支持的参数及示例

-Djavax.net.debug=all
-Djavax.net.debug=ssl:handshake:verbose

-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2
-Djdk.tls.client.protocols=TLSv1.1,TLSv1.2

-Dhttp.agent="known agent"
-Djava.net.useSystemProxies=true

-Dhttp.proxyHost=proxy.example.com -Dhttp.proxyPort=8080 -Dhttp.proxyUser=myname -Dhttp.proxyPassword=mypass
-Dhttps.proxyHost=proxy.example.com -Dhttps.proxyPort=8080 -Dhttps.proxyUser=myname -Dhttps.proxyPassword=mypass

-Djavax.net.ssl.trustStore=C:\<....>\java8\jre\lib\security\cacerts -Djavax.net.ssl.trustStorePassword=changeit

-Djavax.net.ssl.keyStore="C:/Users/Lokesh\keys\maven.jks" -Djavax.net.ssl.keyStorePassword="test"
-Djavax.net.ssl.trustStore="C:/Users/Lokesh\keys\maven.jks" -Djavax.net.ssl.trustStorePassword="test"
 

你可能感兴趣的:(Linux)