如何解决由于 TLS 版本不兼容导致的问题
在实际开发或实施的过程中,你很可能会遇到 TLS 版本不兼容的问题,我们以 Java 为例,你会收到如下报错。
如果你是一名新手,又是看到 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 放开,实现我们的需求。
通过以上这些修改,我们就可以让 JDK17 支持 TLS1.0 和 TLS1.1 了。
我们可以通过以下代码来验证:
我们也可以在运行应用时禁用:
通过以上这么一讲,你那么一改,这个问题就解决了。
那么,为什么不去升级 TLS 版本到较安全的呢,话是这么说,关键是你得两头说的都算,否则只能去兼容。
版权声明: 本文为 InfoQ 作者【JefferLiu】的原创文章。
原文链接:【http://xie.infoq.cn/article/a444df132485d70510a2dae88】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论