旧版JDK8(8u111)无法识别自定义CA签名证书问题咨询
Java 8u111 SSL握手失败问题排查与解答
问题场景
我们正尝试保障Java程序与远程服务器的连接安全,服务器出示由自定义CA签名的证书,但Java程序抛出以下错误:
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023)
该错误仅在JDK 8u111中出现,JDK 8u401可正常运行。两个版本的JDK使用的$JAVAHOME/jre/lib/security/cacerts为同一文件的符号链接,且通过keytool -list确认该文件已包含我们的CA证书:
Certificate fingerprint (SHA-256): 57:4D:F6:93:1E:27:80:39:66:7B.....
OURCOMPANY
Certificate fingerprint (SHA-256): 83:81:CF:C1:68:99:29:F0:D2:C1.....
OURCOMPANY
问题解答
1. 证书本身是否存在导致旧版JDK无法使用的因素?
- 大概率是证书的签名算法、密钥长度或关联SSL配置的兼容性问题。JDK 8u111属于早期补丁版本,对部分现代安全算法的支持不完善,而8u401经过多次补丁更新,补充了更多算法与协议支持。此外,证书链中若包含8u111不支持的扩展字段或加密套件,也会触发握手失败。
2. 是否是SHA-256摘要方法不被旧版JDK识别?
- 不是。JDK 8原生支持SHA-256摘要算法,但8u111对SHA-256作为签名算法的场景支持有限——比如当证书使用
SHA-256withRSA签名,但服务器协商的SSL协议套件要求TLS 1.2(8u111默认未完全启用TLS 1.2),就会导致握手失败。
3. 能否不升级JDK启用SHA-256?
- 可以尝试以下两种方案:
- 添加JVM启动参数,强制启用TLS 1.2协议(SHA-256通常搭配TLS 1.2使用):
-Dhttps.protocols=TLSv1.2 -Djdk.tls.client.protocols=TLSv1.2 -Djavax.net.ssl.enabledProtocols=TLSv1.2 - 修改
$JAVAHOME/jre/lib/security/java.security配置文件,检查jdk.tls.disabledAlgorithms参数,确保未禁用SHA-256相关算法,若有则移除对应限制项。
- 添加JVM启动参数,强制启用TLS 1.2协议(SHA-256通常搭配TLS 1.2使用):
4. 能否用RSA 1024指纹将CA证书导入旧版密钥库?
- 首先明确:指纹是证书的哈希值,RSA 1024是密钥长度,二者概念不同。你的CA证书已存在于密钥库中,重新导入无法解决问题。8u111支持RSA 1024密钥,但如果当前CA证书使用的是RSA 2048+密钥或
SHA-256withRSA以上的签名算法,旧JDK的支持存在局限。 - 若要适配旧JDK,可尝试生成使用
SHA-1withRSA签名的CA证书(但SHA-1已被列为不安全算法,不推荐生产环境使用),或确保证书使用的密钥长度与签名算法在8u111的官方支持列表内。
内容的提问来源于stack exchange,提问作者Mikhail T.
相关产品推荐
相关产品推荐

