
本文详解如何在 JMeter(5.4.2+)中修复因客户端 TLS 协议限制导致的 SSLHandshakeException,重点介绍通过调整 JDK 安全配置启用 TLS 1.0 的安全、可控方法。
本文详解如何在 jmeter(5.4.2+)中修复因客户端 tls 协议限制导致的 `sslhandshakeexception`,重点介绍通过调整 jdk 安全配置启用 tls 1.0 的安全、可控方法。
在使用 JMeter 5.4.2(或更高版本)测试老旧 SOAP 服务时,若目标服务器仅支持 TLS 1.0 协议,而客户端 JDK 默认禁用该协议,就会触发典型的握手异常:
javax.net.ssl.SSLHandshakeException: The server selected protocol version TLS10 is not accepted by client preferences [TLS12]
该错误并非 JMeter 自身限制,而是底层 JDK(尤其是 Java 8u291+、Java 11+ 及主流 OpenJDK 发行版如 Microsoft Build of OpenJDK)出于安全合规要求,在 java.security 文件中默认禁用 TLSv1 和 TLSv1.1 所致。即使你使用的是 JDK 8,较新更新版本(如 8u291、8u301 等)已同步引入此策略。
✅ 正确解决路径:精准启用 TLS 1.0(非降级 JDK)
不推荐回退到极旧 JDK(如 8u101),因其存在已知高危漏洞且缺乏长期维护。推荐做法是在保持当前 JDK 版本的前提下,有选择地启用 TLS 1.0:
步骤 1:定位并编辑 java.security 文件
该文件位于 JDK 安装目录下的:
$JAVA_HOME/jre/lib/security/java.security(JDK 8)
或
$JAVA_HOME/conf/security/java.security(JDK 9+)
⚠️ 注意:确保修改的是 JMeter 实际使用的 JDK —— 可通过 jmeter -v 或检查 jmeter.bat/sh 中的 JAVA_HOME 确认。
步骤 2:修改 jdk.tls.disabledAlgorithms 配置
找到如下行(通常在文件中段):
jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
include jdk.disabled.namedCurves✅ 安全修改方案(推荐):仅移除 TLSv1,保留 TLSv1.1 禁用(因 TLS 1.1 同样存在已知风险,且多数合规场景仅需 TLS 1.0 临时兼容):
jdk.tls.disabledAlgorithms=SSLv3, TLSv1.1, RC4, DES, MD5withRSA, \
DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
include jdk.disabled.namedCurves? 验证提示:TLSv1(注意大小写与空格)必须被完全删除,不可注释或替换为 TLS10;Java 安全属性不识别 TLS10 别名,只识别标准名称 TLSv1。
步骤 3:重启 JMeter 并验证
保存文件后,彻底关闭所有 JMeter 进程(包括后台隐藏实例),重新启动。建议在测试计划中添加「Debug Sampler」+「View Results Tree」,观察 HTTPS 请求是否成功建立连接。
? 补充验证:命令行快速确认 TLS 支持状态
可在终端执行以下命令,确认当前 JVM 是否允许 TLSv1:
$JAVA_HOME/bin/java -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -cp . TestTls
其中 TestTls.java 示例代码如下(用于快速验证):
import javax.net.ssl.*;
import java.io.IOException;
public class TestTls {
public static void main(String[] args) throws Exception {
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, null, null);
SSLSocketFactory sf = ctx.getSocketFactory();
System.out.println("Supported protocols: " + java.util.Arrays.toString(((SSLSocket)sf.createSocket()).getSupportedProtocols()));
System.out.println("Enabled protocols: " + java.util.Arrays.toString(((SSLSocket)sf.createSocket()).getEnabledProtocols()));
}
}⚠️ 重要注意事项与最佳实践
- 仅限测试环境启用 TLS 1.0:TLS 1.0 已于 2021 年被 PCI DSS、NIST 等标准正式弃用。生产环境应推动服务端升级至 TLS 1.2+。
- 避免全局启用 TLSv1.1:除非明确需要,否则不要移除 TLSv1.1 —— 它比 TLS 1.0 更脆弱,且多数现代客户端已弃用。
- JMeter 启动参数无效?:-Dhttps.protocols=TLSv1,TLSv1.2 等 JVM 参数对 Apache HttpClient(JMeter 默认 HTTP 实现)不生效,因其受 java.security 全局策略强制约束。
- IBM JDK 用户注意:错误堆栈中出现 com.ibm.jsse2.* 表明你正在使用 IBM JRE。其配置路径为 $JAVA_HOME/jre/lib/security/java.security,修改方式相同,但需确认 IBM JDK 版本是否支持动态启用(建议优先切换至 OpenJDK)。
- 容器/CI 环境适配:若在 Docker 或 CI 中运行 JMeter,请将修改后的 java.security 文件作为构建步骤注入镜像,或通过挂载卷方式覆盖。
✅ 总结
根本原因在于 JDK 安全策略主动拒绝 TLS 1.0 握手,而非 JMeter 功能缺失。通过精准编辑 java.security 中的 jdk.tls.disabledAlgorithms 属性,仅解除对 TLSv1 的禁用,即可在保障基础安全边界的前提下完成兼容性测试。该方案稳定、可审计、无需版本降级,是企业级性能测试中应对遗留系统 TLS 兼容问题的标准实践。








