如何在JDK1.8u181及更高版本中成功禁用SSLv2Hello协议
问题根因
JDK 1.8u171及后续版本调整了jdk.tls.disabledAlgorithms配置的生效逻辑:全局配置中禁用的SSLv2Hello只会限制默认启用的协议列表,如果代码中显式调用setEnabledProtocols(socket.getSupportedProtocols())主动把SSLv2Hello加入启用列表,全局配置默认不会拦截,这就是u40版本配置生效、u181版本失效的核心原因。
可用解决方案
方案1:调整代码逻辑(最稳妥)
不要直接把所有支持的协议设为启用,手动过滤掉SSLv2Hello后再设置,示例修改如下:
// 替换原代码中的 socket.setEnabledProtocols(socket.getSupportedProtocols()); List<String> enableProtocols = new ArrayList<>(Arrays.asList(socket.getSupportedProtocols())); // 移除不安全的协议 enableProtocols.remove("SSLv2Hello"); enableProtocols.remove("SSLv3"); socket.setEnabledProtocols(enableProtocols.toArray(new String[0]));
如果没有特殊需求,也可以直接删除setEnabledProtocols调用,使用JDK默认的启用协议列表,此时java.security中的禁用配置会自动生效。
方案2:无需修改代码,调整启动参数/配置
如果不方便修改业务代码,可以用以下两种方式强制禁用:
- 方式一:在JVM启动参数中添加更高优先级的禁用配置,优先级高于
java.security文件:
-Djdk.tls.disabledAlgorithms="SSLv3, SSLv2Hello, RC4, MD5withRSA, DH keySize < 1024, EC keySize < 224, DES40_CBC, RC4_40"
- 方式二:额外指定客户端默认启用的协议列表,直接排除SSLv2Hello:
-Djdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2"
验证方式
启动时添加JVM参数-Djavax.net.debug=ssl,handshake,查看握手日志,确认输出的启用协议列表中没有SSLv2Hello即可,也可以配合抓包工具确认握手格式。
内容的提问来源于stack exchange,提问作者Sudheer
相关产品推荐
相关产品推荐

