金蝶云星空 (9.0版本) ERP的WebApi接口随机出现SSLException

发布于:2025-07-03 ⋅ 阅读:(15) ⋅ 点赞:(0)

环境:

        java-1.8.0-openjdk-1.8.0.131

        hutool-all 依赖, 5.8.25版本

项目背景:

        发版上线,用的hutool工具类 HttpUtil.createPost() ,请求域名为https://xxx.ik3cloud.com/k3cloud 的金蝶ERP webapi接口

问题:

      报各类 SSLException 异常.....

原因: 


    服务端要求的TLS版本,与客户端实际请求的TLS版本不一致

解决过程: 


    6月19号,在发送post请求前,java代码中明确加上  System.setProperty("https.protocols", "TLSv1.2");代码后,接口能正常调用。


6月24号上午9点27分
日志突然出现大量 : SSLException: Received fatal alert: protocol_version 异常信息....

cn.hutool.core.io.IORuntimeException: SSLException: Received fatal alert: protocol_version
	at cn.hutool.http.HttpRequest.send(HttpRequest.java:1350)
	at cn.hutool.http.HttpRequest.doExecute(HttpRequest.java:1188)
	at cn.hutool.http.HttpRequest.execute(HttpRequest.java:1051)
	at cn.hutool.http.HttpRequest.execute(HttpRequest.java:1027)

Caused by: javax.net.ssl.SSLException: Received fatal alert: protocol_version
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:208)
	at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
	at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2020)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1127)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
	at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1334)
	at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1309)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:259)
	at cn.hutool.http.HttpConnection.getOutputStream(HttpConnection.java:458)
	at cn.hutool.http.HttpRequest.sendFormUrlEncoded(HttpRequest.java:1367)
	at cn.hutool.http.HttpRequest.send(HttpRequest.java:1342)
	... 8 common frames omitted

引入额外的openjsse依赖 Java8支持TLSv1.3协议请求,问题依旧。。。。。。

于是,查看 该域名用到的TLS具体版本:

yum install nmap
nmap --script ssl-enum-ciphers -p 443 xxx.ik3cloud.com

发现浏览器中 该域名的TLS版本 是1.3 ,但服务器端检查该域名的TLS版本是1.2 ,故项目中的java代码加上如下设置,兼容 TLSv1.2 与 TLSv1.3 版本:
 

System.setProperty("https.protocols", "TLSv1.2,TLSv1.3");
System.setProperty("jdk.tls.client.protocols", "TLSv1.2,TLSv1.3");


运行半小时后,依旧偶尔报错:

Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

cn.hutool.core.io.IORuntimeException: SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
        at cn.hutool.http.HttpRequest.send(HttpRequest.java:1350)
        at cn.hutool.http.HttpRequest.doExecute(HttpRequest.java:1188)
        at cn.hutool.http.HttpRequest.execute(HttpRequest.java:1051)
        at cn.hutool.http.HttpRequest.execute(HttpRequest.java:1027)
        
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
        at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171)
        at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:106)
        at sun.security.ssl.TransportContext.kickstart(TransportContext.java:245)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:410)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:389)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:558)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:201)
        at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1390)
        at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1365)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:264)
        at cn.hutool.http.HttpConnection.getOutputStream(HttpConnection.java:458)
        at cn.hutool.http.HttpRequest.sendFormUrlEncoded(HttpRequest.java:1367)
        at cn.hutool.http.HttpRequest.send(HttpRequest.java:1342)
        ... 7 common frames omitted

java代码中,使用与金蝶ERP服务器一致的加密套件,

# 通过如下命令,查询金蝶服务器端所用的加密套件
openssl s_client -connect XXX.ik3cloud.com:443 -tls1_2
// 使用与金蝶服务端 一致的加密套件
System.setProperty("https.cipherSuites", "ECDHE-RSA-AES256-GCM-SHA384");

也依旧报Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

于是向金蝶客服提工单,金蝶技术建议用JDK11:

于是升级jdk为 open jdk11.0.2  ,刚开始正常,半个小时后 偶发性的报错 Caused by: javax.net.ssl.SSLException: No PSK available. Unable to resume.

javax.net.ssl.SSLException: No PSK available. Unable to resume.

 原因jdk11版本过低: 这是一个jdk11的已知bug:https://bugs.openjdk.java.net/browse/JDK-8213202


最后使用jdk11的最新版本: oracle jdk11.0.27 ,再无以上SSLException异常,

至此,问题解决

附录:

Java默认使用的协议版本


参考文档:


https.protocols在Java中的使用

JAVA HTTPS单向认证和双向认证以及JDK低版本请求

引入额外的openjsse依赖 Java8支持TLSv1.3协议请求

解决No PSK available. Unable to resume编译报错的问题