写点什么

如何解决由于 TLS 版本不兼容导致的问题

作者:JefferLiu
  • 2023-05-12
    辽宁
  • 本文字数:1246 字

    阅读完需:约 4 分钟

如何解决由于TLS版本不兼容导致的问题

在实际开发或实施的过程中,你很可能会遇到 TLS 版本不兼容的问题,我们以 Java 为例,你会收到如下报错

The server selected protocol version TLS10 is not accepted by client preferences [TLS13, TLS12]。
复制代码

如果你是一名新手,又是看到 TLS 这种底层的东西,一定让你感觉到束手无策,拼命的再网上找各种解决方案,而网上基于这个问题的帖子,大多是拷贝来拷贝去,只言片语,也没说清楚了啥,说以你看了,也并不一定敢上手去尝试。


我也是命好,最近遇到这个事儿,顺手记录下来分享给大家。


遇到这个问题大家不用慌,首先这是一个非常简单的问题,本质就是:

在进行网络调用的过程中,客户端和服务端采用的 TLS 版本不一致,导致握手失败。通俗说就是语言不通,无法交流,系统把这个错误报给了你。


比如下图两台服务器:

Jenkins 从 CSM 服务器上下载代码进行构建。Jenkins 使用的是 JDK17,SCM 使用的事 VisualSVN3.9 或以下。


那么我们可以分别看一下这两个软件对 TLS 版本的支持:

JDK17 是支持 TLS1.0 ~ TLS1.3 的。

但是,官方强调了,从 JDK 6 到 JDK 7,默认使用的 TLS 版本是 TLS 1.0。JDK 8 开始,默认使用的 TLS 版本是 TLS 1.2。JDK 11 开始,支持 TLS 1.3。JDK 17 默认使用的 TLS 版本是 TLS 1.3。


VisualSVN3.9 默认支持 TLS1.0 和 TlS1.1 以下。所以看下图:


这两家是无法现实握手的,就是不兼容,系统会报出本文最开始的错误。很简单!


那么问题原因找到了,我们来解决它。解决思路就是让两边的协议有交集。比如都要支持 TLS1.0 或 TLS1.2.

但是要注意:JDK 的 TLS 1.0 和 TLS 1.1 实现存在安全漏洞,建议不要使用。

我们让两边同时支持 TLS1.0 版本,因为是内网系统,问题不大。


从上面的表格中,我们可以看到,JDK17 是支持 1.0 的,为什么不能用,是因为在他的安全配置中,已经把 1.0 给禁用了,我们可以把 1.0 放开,实现我们的需求。

这个配置文件的位置是:$JAVA_HOME/conf/security/java.security
找到里面的一行配置:jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \ DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL 说明:JDK中的jdk.tls.disabledAlgorithms参数用于禁用不安全或不需要的TLS密码算法,以提高系统的安全性。通过配置这个参数,可以指定JDK不支持的密码算法或协议,以降低它们的优先级,减少被攻击的风险。
我们把TLSv1,TLSv1.1这两个删除掉,变成如下:jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, \ DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL
复制代码

通过以上这些修改,我们就可以让 JDK17 支持 TLS1.0 和 TLS1.1 了。


我们可以通过以下代码来验证:

System.out.println(SSLContext.getDefault().getSupportedSSLParameters().getProtocols());
复制代码

我们也可以在运行应用时禁用:

// 不禁用就是可以用java -Djdk.tls.disabledAlgorithms="SSLv3, RC4" myApp
复制代码


通过以上这么一讲,你那么一改,这个问题就解决了。


那么,为什么不去升级 TLS 版本到较安全的呢,话是这么说,关键是你得两头说的都算,否则只能去兼容。


发布于: 刚刚阅读数: 5
用户头像

JefferLiu

关注

复杂的东西简单讲,简单的东西深刻讲。 2018-08-21 加入

已昏懒人

评论

发布
暂无评论
如何解决由于TLS版本不兼容导致的问题_Java_JefferLiu_InfoQ写作社区