2018年3月6日 星期二

JDK1.6 SSLHandshakeException

前陣子在做安全協定升級,從 HTTP over SSL 升級為 HTTP over TLS v1.1、TLS v1.2。
新服務僅允許使用 TLS v1.2 Protocol ,因為 Google 早在 2014年10月就發布在 SSL 3.0 中發現設計缺陷,建議禁用此一協議。詳情請看 wiki
這時候發現個問題 JDK 各版本對於 TLS Protocols 支援不同,如下表。
JDK 8. (March 2014 to present) JDK 7. (July 2011 to present) JDK 6. (2006 to end of public updates 2013)
TLS Protocols TLSv1.2 (default)、TLSv1.1、TLSv1、SSLv3 TLSv1.2、TLSv1.1、TLSv1 (default)、SSLv3 TLS v1.1(JDK 6 update 111 and above)、TLSv1 (default)、SSLv3
因為 JDK 6 dafault 是 TLSv1,並且不支援 TLS v1.2,除非升級至 JDK 6u121need support contract)。
所以當使用 JDK 6 or 7 的程式要去呼叫使用 HTTP over TLS v1.2 Protocol 的位置時,就會出現以下錯誤
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
       at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946)
       at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
       at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
       at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
       at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)
       at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
       at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1091)
       at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)
       at com.labcorp.efone.vendor.TestATTConnectivity.main(TestATTConnectivity.java:43)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
       at sun.security.ssl.InputRecord.read(InputRecord.java:482)
       at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927)
       ... 8 more
這個錯誤的意思是遠端服務在交握時關閉連線,這個錯在 StackOverflow 也有答案了,參考此
解決方法有幾種:
  1. 啟動服務時,設定 https.protocols 環境變數,讓 JVM 啟動時載入 HttpsURLConnection;-Dhttps.protocols=TLSv1.1,TLSv1.2
  2. 建立連線前,設定 https.protocols 環境變數;System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");
  3. Customizing SSL in HttpClient 3.x
  4. 升級至 JDK 8

Reference material:

沒有留言:

張貼留言