TLS版本检测失败求助:HOST A运行Java测试程序报错原因排查
问题:HOST A执行TLS版本检测Java程序失败排查
我有一个基于TLS/SSL运行的Web应用,密钥库路径为**/home/devusr1/certs/default.jks**。编写了如下Java测试程序用于检测TLS版本:
package com.devpkg.stage1; import javax.net.ssl.HttpsURLConnection; import java.net.URL; public class TlsVersionChecker { private static final String KEYSTORE = "keystore"; private static final String ADDRESS = "address"; public static void main(String[] args) { try { String KS = System.getProperty(KEYSTORE); String AD = System.getProperty(ADDRESS); System.setProperty("javax.net.ssl.keyStore", KS); System.setProperty("javax.net.ssl.keyStorePassword", "kspwd123"); System.setProperty("javax.net.ssl.trustStore", KS); System.setProperty("javax.net.ssl.trustStorePassword", "kspwd123"); System.setProperty("javax.net.debug", "ssl,handshake"); URL url = new URL(AD); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); connection.connect(); } catch (Exception e) { e.printStackTrace(); } } }
在HOST A的命令行中使用Java 11执行该程序时返回失败,报错信息如下:
bash-4.4$ java -Dkeystore=/home/devusr1/certs/default.jks -Daddress=https://ARCDEV12.devpkg.com:8080 -cp TlsVersion.jar com.devpkg.stage1.TlsVersionChecker javax.net.ssl|DEBUG|01|main|2025-01-02 14:27:46.642 PST|SSLCipher.java:464|jdk.tls.keyLimits: entry = AES/GCM/NoPadding KeyUpdate 2^37. AES/GCM/NOPADDING:KEYUPDATE = 137438953 javax.net.ssl.SSLException: TLS initialization was not previously performed for this job. at com.ibm.i5os.jsse.JSSESocket.processResult(JSSESocket.java:1980) at com.ibm.i5os.jsse.JSSESocket.startHandshake(JSSESocket.java:1703) at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:580) at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:201) at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:168) at com.rs.rdo.TlsVersionChecker.main(TlsVersionChecker.java:25) bash-4.4$
但在同样使用Java 11的HOST B上运行该程序却能正常执行,输出如下:
bash-5.2$ java -Dkeystore=/home/devusr1/certs/default.jks -Daddress=https://ARCDEV16.devpkg.com:8080 -cp TlsVersion.jar com.devpkg.stage1.TlsVersionChecker javax.net.ssl|DEBUG|01|main|2025-01-02 16:25:10.055 CST|SSLCipher.java:464|jdk.tls.keyLimits: entry = AES/GCM/NoPadding KeyUpdate 2^37. AES/GCM/NOPADDING:KEYUPDATE = 137438953 javax.net.ssl|DEBUG|01|main|2025-01-02 16:25:18.193 CST|Utilities.java:73|the previous server name in SNI (type=host_name (0), value=ARCDEV16.devpkg.com) was replaced w0), value=ARCDEV16.devpkg.com) javax.net.ssl|WARNING|01|main|2025-01-02 16:25:18.212 CST|SignatureScheme.java:295|Signature algorithm, ed25519, is not supported by the underlying providers javax.net.ssl|WARNING|01|main|2025-01-02 16:25:18.213 CST|SignatureScheme.java:295|Signature algorithm, ed448, is not supported by the underlying providers javax.net.ssl|INFO|01|main|2025-01-02 16:25:18.217 CST|AlpnExtension.java:178|No available application protocols javax.net.ssl|DEBUG|01|main|2025-01-02 16:25:18.217 CST|SSLExtensions.java:260|Ignore, context unavailable extension: application_layer_protocol_negotiation javax.net.ssl|DEBUG|01|main|2025-01-02 16:25:18.218 CST|SSLExtensions.java:260|Ignore, context unavailable extension: cookie javax.net.ssl|DEBUG|01|main|2025-01-02 16:25:18.245 CST|SSLExtensions.java:260|Ignore, context unavailable extension: renegotiation_info javax.net.ssl|DEBUG|01|main|2025-01-02 16:25:18.245 CST|PreSharedKeyExtension.java:633|No session to resume. javax.net.ssl|DEBUG|01|main|2025-01-02 16:25:18.245 CST|SSLExtensions.java:260|Ignore, context unavailable extension: pre_shared_key javax.net.ssl|DEBUG|01|main|2025-01-02 16:25:18.253 CST|ClientHello.java:642|Produced ClientHello handshake message ( "ClientHello": { "client version" : "TLSv1.2", ... "ServerHello": { "server version" : "TLSv1.2", ...
请问为何HOST A上执行失败,能否帮忙排查原因?
排查分析
从报错信息里的com.ibm.i5os.jsse.JSSESocket可以看出,HOST A用的是IBM i5/OS平台定制的JSSE实现,而非标准OpenJDK的JSSE,这是两台主机的核心差异。结合报错TLS initialization was not previously performed for this job,可以从以下几个方向排查:
- 平台特定初始化要求:IBM i5/OS(原AS/400)的JSSE实现,要求建立TLS连接前必须先完成TLS环境的初始化,比如需要设置特定系统属性
com.ibm.jsse2.overrideDefaultTLS=true,或者在作业层面配置TLS相关系统参数;而HOST B是标准Linux环境的OpenJDK,没有这个限制。 - Java环境差异:虽然都是Java 11,但HOST A的Java是IBM针对i5/OS定制的版本,HOST B是标准OpenJDK。两者JSSE实现逻辑不同,IBM版本对作业上下文依赖更强,需要确保当前作业的TLS环境已正确初始化。
- 目标服务器差异:HOST A连接的是
ARCDEV12.devpkg.com:8080,HOST B连接的是ARCDEV16.devpkg.com:8080,两台服务器的TLS配置可能存在差异。比如ARCDEV12要求特定的TLS扩展或握手流程,IBM i5/OS的JSSE未处理这种情况,导致初始化失败。 - 密钥库兼容性:虽然密钥库路径相同,但IBM i5/OS对JKS文件的处理可能存在细节差异,比如文件权限、存储格式等。可以在HOST A上执行以下命令验证密钥库有效性:
keytool -list -keystore /home/devusr1/certs/default.jks -storepass kspwd123
解决建议
- 在HOST A的Java程序中添加IBM i5/OS JSSE的初始化配置:在设置SSL属性后添加
System.setProperty("com.ibm.jsse2.overrideDefaultTLS", "true"),或者设置com.ibm.i5os.jsse.enableTLSInitialization=true。 - 检查HOST A的作业配置,确保当前作业已启用TLS支持(可通过i5/OS的系统管理工具查看作业安全属性)。
- 对比两台主机的Java版本细节:执行
java -version确认HOST A是IBM JDK、HOST B是OpenJDK,针对性调整代码适配IBM JDK的要求。 - 尝试使用IBM提供的
SSLSocketFactory替代默认实现,确保符合i5/OS的TLS初始化流程。
内容的提问来源于stack exchange,提问作者Boykaczhu
相关产品推荐
相关产品推荐

