前言
遇到這個問題得說一下筆者的開發環境,筆者所在公司,平時開發用的web容器是jboss,使用的JDK是oracle的JDK,但是測試和生產環境用的是WAS,JDK用的是IBM的JDK,由於項目的不同,測試環境所安裝的web容器和JDK版本都並不相同。這個也是筆者遇到問題的原因所在。
筆者在公司負責一個項目的開發,該項目有一個功能需要調用到公司另一個項目的接口,而那個項目提供的接口是基於HTTPS的,所以筆者在進行調用的時候,使用了JDK提供的SSL連接進行了請求。
SSLContext.getInstance(“SSL”);
該代碼,筆者在自己本機的JBoss上測試過,並沒有問題。可是,發布到was里面之后,程序一直沒法成功調用接口,通過日志追蹤后,發現程序在服務器運行的時候后台報了異常,該異常如下:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshank
握手失敗,網上有人說,該異常是因為證書的原因,可是筆者嘗試過后發現,該說法並不對應筆者所描述的場景,最后在同事的幫助下找到了原因。
該問題出現的原因在於SSL協議的版本不同。發現問題之后,筆者分析了一下具體情況。由於項目的原因,筆者現在用的JDK版本還是1.5的,同時,筆者去調的項目也是個老項目,用的JDK版本也是1.5的。所以當筆者通過本地測試的時候,SSL的請求方和接收方的版本是一致的,並沒有問題。可是由於項目的擴容,筆者項目的測試環境前陣子進行了遷移,新的測試環境采用的是IBM的JDK1.6。因為JDK版本不同,默認采用的握手協議不同,所以導致兩邊程序進行握手的時候會失敗。
仔細查詢了一下資料后發現,原來oracle的JDK默認采用的是TLSv1和TLSv2進行嘗試握手連接的,而IBM新的JDK采用的是SSLv3,新老版本還不一樣。
詳細的資料地址:http://www-01.ibm.com/support/docview.wss?uid=swg21687173
該問題的解決方法有兩個:
方法一:修改獲取SSL連接的的代碼(筆者使用的方法,簡單)
SSLContext.getInstance(“TLS”);
方法二:更新IBM的JDK
在上面給出的鏈接中,其實IBM已經意識到自己的問題,也給出了另外一個補丁,據說更新后就能成功(筆者沒嘗試過( ̄▽ ̄)”)
本文章同步發布至 http://blog.e65535.com/2017/01/15/ssl-excepiton/