记录一次https通讯调试过程

写在前面,感谢无数工程师的无私奉献,本文是基于网上文章分享得出的解决办法。

情况说明:和服务端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:[]"

经查阅资料,了解一般请求方在交互过程中,会校验证书包含的一些信息,其中会有目标域和证书中的CN是否匹配,如下:

[下载服务端公钥证书命令:openssl s_client -connect www.zjoj.com.cn:5858  或者  openssl s_client -connect 121.41.60.113:5858 ]

 由于直接指定IP时,IP和CN值不匹配,导致证书验证失败,提示交互失败。

解决办法:

  1. 直接使用域名访问;
  2. 使用指定IP访问时,自定义变量Host为域名的值,这样校验时就会用Host的值与证书的CN值做比较;
  3. 代码里不对证书CN值做校验(不推荐,有安全风险)

写在后面:

由于当前项目使用的jdk版本为1.6,不支持一些协议算法,比如TLS(SSL协议的升级版),解决办法如下:

  1. 可以考虑手工将所需算法补充到当前jdk中,
  2. 或者引用三方的BouncyCastle包可以解决,
  3. 或者直接升级jdk到idk1.8.0 162及更高版本。
posted @ 2024-06-22 10:21  tomato_4  阅读(69)  评论(0编辑  收藏  举报