情況說明:和服務端https互動時,用域名的方式會有正常的應答,用指定IP的方式則提示異常。
程式碼丟擲異常如下:
javax.net.ssl.SSLHandshakeException:Remote host closed connection during handshake at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl,java:882) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSSocketImpl.java:1188) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSSocketImpl.java:654) at com.sun.net.ssl.internal.ssl.AppOutputstream.write(AppOutputstream.java:100) at org.apache.http.impl.io.AbstractSessionoutputbuffer.flushBuffer(AbstractSessionOutputBuffer java:131) [httpcore-4 1.4.jar:4.1.4)
用curl測試如下:
curl -X Post -H "Content-Type:application/json" "https://www.zjoj.com.cn:5858/api/Bank/SaveBankAccount?appid=10016" {"data":false,"code":104,"message":"Object reference not set to an instance of an object."}
curl -X Post -H "Content-Type:application/json" "https://121.41.60.113:5858/api/Bank/SaveBankAccount?appid=10016" curl: (60) schannel: SNI or certificate check failed: SEC_E_WRONG_PRINCIPAL (0x80090322) - 目標主要名稱不正確。 More details here: https://curl.se/docs/sslcerts.html curl failed to verify the legitimacy of the server and therefore could not establish a secure connection to it. To learn more about this situation and how to fix it, please visit the web page mentioned above.
在idea使用JetClient,測試結果如下:
報錯資訊為"Certificate for 121.41.60.113> doesn't match any of the subject alternative names:[]"
經查閱資料,瞭解一般ssl證書驗證,會校驗證書包含的一些資訊,其中會有目標域和證書中的CN是否匹配,如下:
由於直接指定IP時,IP和DN值不匹配,導致證書驗證失敗,提示互動失敗。
解決辦法:
- 直接使用域名訪問;
- 使用指定IP訪問時,自定義變數Host為域名的值,這樣校驗時就會用Host的值與證書的DN值做比較;
- 程式碼裡不對證書DN值做校驗(不推薦,有安全風險)
寫在後面:
由於當前專案使用的jdk版本為1.6,不支援一些演算法,比如TLS,可以考慮手工將所需演算法補充到當前jdk中,或者直接升級jdk到idk1.8.0 162及更高版本。