記一次https通訊除錯過程

tomato_4發表於2024-06-22

情況說明:和服務端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值不匹配,導致證書驗證失敗,提示互動失敗。

解決辦法:

  1. 直接使用域名訪問;
  2. 使用指定IP訪問時,自定義變數Host為域名的值,這樣校驗時就會用Host的值與證書的DN值做比較;
  3. 程式碼裡不對證書DN值做校驗(不推薦,有安全風險)

寫在後面:

由於當前專案使用的jdk版本為1.6,不支援一些演算法,比如TLS,可以考慮手工將所需演算法補充到當前jdk中,或者直接升級jdk到idk1.8.0 162及更高版本。

相關文章