问题出现:
jdk版本从7升级到8之后,出现ssl异常信息:具体错误信息如下:
- 问题定位
关于ssl握手异常,网上有很多。大多数的解决方式都是修改protocols、cipherSuites、修改${JAVA_HOME}/lib/security的local_policy.jar、US_export_policy.jar或者修改jdk版本。
在尝试了所有的方法法之后,还是握手异常。最后在启动java程序时,新增了调试参数
-Djavax.net.debug=all
可以开启加密协议的调试模式。
对比握手成功和握手失败的协议报文,发现握手失败报文缺少Cipher Suites没有RC4相关的加密算法(SSL_RSA_WITH_RC4_128_SHA)。
在查看客户端连接的代码发现,在创建SSLConnectionSocketFactory没有指定支持的protocols和Cipher Suites。导致ssl握手过程中使用了jdk8默认的ssl协议TLSv1.2,并且jdk8默认的Cipher Suites禁用了RC4算法。最终导致握手失败。
修复代码如下:
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[]{"TLSv1","TLSv1.1","TLSv1.2"},
new String[]{"SSL_RSA_WITH_RC4_128_SHA"},
new NoopHostnameVerifier()
);
修改之后还是握手异常!
- 问题再定位
因为在从JDK 1.8.0_u60开始,默认禁止了RC4这个算法。可以在{JRE_HOME}/lib/security/java.security找到相关配置:
jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 768
以及
jdk.tls.legacyAlgorithms= \
K_NULL, C_NULL, M_NULL, \
DHE_DSS_EXPORT, DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, \
DH_RSA_EXPORT, RSA_EXPORT, \
DH_anon, ECDH_anon, \
RC4_128, RC4_40, DES_CBC, DES40_CBC
- 问题解决
启用Java的RC4算法
方法一:
修改 {JRE_HOME}\lib\security\java.security文件如下:
方法二:
在代码中指定属性如下:
Security.setProperty("jdk.tls.disabledAlgorithms","SSLv3, DH keySize < 768");
然后启用相关的协议和Cipher Scites。