https://segmentfault.com/a/1190000021559557
此文主要内容翻译至博客How to Fix the SSL/TLS Handshake Failed Error?,并做了一些添加,修改和删除.
当浏览器向web服务器(如Apache)发送一个安全的请求时,ssl/tls握手过程就开始了.ssl/tls错误时有发生,其中最常见的错误就是SSL Handshake Failed error
.下面我们就来讲解什么是SSL/TLS握手失败,以及如何解决.
在讲述tls握手失败问题之前,有必要先简述一下tls握手过程:
从以上tls握手过程来看,出现tls握手失败的原因有很多.只要客户端和服务端的握手过程中的某一个环节出了问题,都有可能导致tls握手失败.下面概括出现tls握手失败的一些常见问题.
原因 | 描述 | 哪里修复 |
---|---|---|
系统时间不准确 | 客户端的日期或时间不准确 | 客户端 |
浏览器错误 | 浏览器设置导致的错误 | 客户端 |
中间人 | 连接被第三方操控或劫持 | 客户端 |
协议不匹配 | 服务端不支持客户端所使用的协议 | 服务端 |
加密套件不匹配 | 服务端不支持客户端使用的加密套件 | 服务端 |
服务端启用了服务器名称指示(SNI-Enabled) | 由于启用了SNI导致服务端无法与客户端完成通信 | 服务端 |
证书错误 |
|
服务端 |
下面,我们来详细的了解一下为何以上原因会导致tls握手失败,以及如何解决.
通常tls握手失败都是由服务端以及服务端tls配置问题导致的.
目前最主要的原因就是服务端的tls配置不支持ssl3.0.但是,客户端这边的问题也很有可能会导致的tls握手失败.比如,像系统时间不正确,或者浏览器更新所至等一些常见的客户端问题.
下面来详细解释一些常见的客户端问题.
这种情况通常不会发生,但有时系统时间会与真实时间不符.
原因是tls认证是有一个特定的有效期的,所以错误的系统时间可能会导致tls握手失败.
如果握手失败是由系统时间显示不正确导致,解决方法就是修正计算机的系统时间.
浏览器(客户端)的某些错误可能导致tls握手失败.例如浏览器某些设置错误,或由某些插件导致等原因,都有可能导致你访问合法网站时发生错误.但是定位和修复浏览器问题是非常困难的,最简单的方法是切换到其他浏览器来访问.
如果切换到其他浏览器还是tls握手失败,那么问题就不是由浏览器本身导致的.但还是有可能是由一些插件导致的,排查一下你的系统里装了哪些可以影响多个浏览器的插件,将它们关闭后,将浏览器恢复默认设置并重启.如果还有问题,那就可能是其他原因导致的.
通常,中间人劫持是一种试图损害或窃取用户信息的犯罪活动.但也不完全是这种情况.处于检查或做负载均衡等原因,许多程序和设备也会先截取信息再将其发送到服务端,这也被称为中间人.
这些中间人设备有时也会导致tls握手失败.原因可能是网络防火墙阻止了连接,或是服务端网络的其他边缘设备的设置导致的.在这种情景下,导致错误的原因既可能来源于客户端,也可能来源于服务端.
如果问题来源于客户端,你可以通过调整自己系统VPN,防毒软件和防火墙的设置来打通连接.
如果问题是由服务端导致的,那大部分是由于网络中的边缘设备配置所造成的问题.
大部分情况下, tls握手失败都是由服务端问题所导致的. 其中有些问题很容易解决, 有些问题不容易解决,甚至有一些问题不值得去解决.
下面来看看一些常见的服务端问题.
这是一个在服务端和客户端都可能出现的错误, 需根据实际情况来判断是否要去解决这个问题. 而且当问题是出现在加密或协议相关时,建议的解决方法是更新到新的版本, 而不是回退到旧版本.
例如:
虽然tls1.2已经诞生十多年了,但仍有一小部分网站还不支持. 而且早在2018年3月, tls1.3的最终版本就在RFC 8446 by the IETF上发版了,并建议所有网站添加对tls1.3版本的支持.
所以, 如果tls握手失败的原因是协议不匹配,那通常原因是服务端和客户端支持的tls版本不同.
例如:
上面这个例子就是tls协议不匹配.但是,在这种情况下,要修复这个问题,不应该是服务端来匹配低版本的协议,而应该是客户端升级到tls1.2来匹配服务端较新的协议. 在目前,我们的建议是必须支持tls1.2和tls1.3协议,对于还不支持的网站必须添加上这两个版本.
tls/ssl并不是通过一个通过自身可以解决所有问题的算法,而是一系列不同算法的结合,不同的算法用以实现不同的功能,它们结合在一起组成了tls/ssl.
tls1.3版本的加密套件得到了进一步的完善.在这之前, 加密套件的算法主要包含以下功能:
不同组织和机构有不同的加密标准, 支持不同的加密套件.所以为了匹配服务端, 客户端必须提供多种加密套件的支持. 同样,一般服务端也会支持多种加密套件.
在网络连接中经常会发生这种情况, 你尝试和服务端建立一个tls连接, 在客户端和服务端之间存在一个边缘设备(如负载均衡, 反向代理等), 这个边缘设备接收并解密了你的https流量,再重新加密发送到在他之后的服务端. 但如果这个边缘设备和服务端之间的加密套件不匹配, 就会导致错误. 同协议版本不匹配类似, 加密套件不匹配时, 通常是采取升级而不是降级来解决问题.
最后强调一点, 被弃用的协议版本或密码套件通常是因为他们存在安全隐患. 所以,如果你采取降级来解决此类问题将会降低https连接的安全性.
许多原因都会导致浏览器判定tls证书不合法, 这时浏览器就会阻止tls握手连接. 在接下来的小节中, 我们会深入探讨由于此类技术问题所引发的tls握手失败问题.
在以前,一个网站的非www域名和www域名之间存在着问题,但是后来证书颁发机构允许一个证书可以签发多个子域名(SAN),已经几乎解决了这个问题.处理证书域名错误的最好方法就是从新签发一个新证书,或者使用通配符证书.
SSL/TLS和PKI信任模型通常依赖于根程序(Root program),这是存储在计算机系统上的受信任CA根证书的集合。其中一些根程序例如:
CA根程序十分重要,虽然它不直接签发证书,但证书机构会利用中间根证书来签发终端用户所使用的tls叶证书. 这就是证书链的运作方式, CA根证书被用来签发中间根, 中间根又用来签发其他中间根, 最终直到终端用户的tls叶证书.
无论什么时候,只要浏览器收到了张tls证书,都会去去检查它签名的真实性. 在签发该证书的中间根中验证它的数字签名,然后再将该中间根的数字签名拿到签发它的中间根上去验证,如此层层递进,最终会追溯到一个受信任的CA根证书.
因此,无论处于什么原因导致这个检验过程不能完整的进行,甚至浏览器只是不能定位其中一个中间根,都会导致tls握手失败的错误.
解决方案是安装缺失了的中间证书.缺失的中间证书可以在你购买tls证书的CA机构网站找到.
当前,tls证书的最大有效期是2年. 因此,如果你的证书过期或者因为某些原因被注销了,将会导致tls握手失败的错误.解决方法是重新购买和安装一份合法的证书.
如果你的暴露在公网上的网站使用的是自签名证书,这是不被信任的,将会导致错误. 要解决这个错误,你需要去一个受信任的CA机构重新签署一份tls证书.
通常,这是一个发生在服务端设备之间的内部问题,但有时一个未开启SNI的客户端去访问一个开启了SNI的服务端,就可能发生tls握手错误.
要解决这个问题,你必须确定服务器的主机名和端口号,同时还要验证服务器是否开启了SNI验证,以及验证服务器是否传递了所有的必要信息.
通常网站管理者不需要做任何改变, 但如果一旦遇到了此类问题,绝对不能忽视. 尽管有时问题是由客户端导致的, 但正如此文中提到的一样,其中大多数情况都是有服务端导致的.
所以,如果你只是一个普通的用户,你能做的事情是有限的. 最好的方法就是将问题上报给网站管理员,等待他们来修复.