TLS 1.3协议的改进分析
网络安全-https
网络安全的基石(一)——加密
网络安全的基石(二)——完整性和身份认证
公钥信任-数字证书和CA
信任始于握手TLS连接过程详解。
TLS 1.3的特性分析
如何优化HTTPS连接-待改进
早在2013年,IETF(互联网工程组)就对TLS 1.2过时的设计和两次往返费用不满,于是开始准备新版本的TLS。同年8月,柳勇·瑞斯寇拉提出了新版TLS的功能愿望清单。经过一番争论,最终将提案内容定义为TLS 1.3。推动TLS 1.3设计的主要问题有:
终于在2018,2010,时隔四年,TLS 1.3的最终版本发布了——RFC-8446。新协议使互联网更快更安全。随着TLS 1.3的采用率越来越高,从长远来看必然会影响互联网的发展。同时,尽快将TLS 1.3顺利应用到在线环境中,无疑是当务之急。
不过在此之前,TLS 1.2的应用已经是10年(2008年)。毕竟经历了各种考验,新协议在推广部署上肯定会带来新的挑战。接下来,我们来看看新版TLS是怎么做的。
由于TLS 1.1/1.2等协议已经出现多年,很多应用和Middlebox只认可旧的记录协议格式,很难更新甚至是僵化的。
可部署性
官方表示,由于这些Middlebox在新的改动中表现不佳,即使是对TLS 1.3协议的微小改动(比如删除冗余的ChangeCipherSpec消息,将版本号从0x03升级到0x04),最终也导致了部分设备的连接失败。这也是TLS 1.3从草案到最终发布用了这么长时间的重要原因之一。
为了保证这些广泛部署的“老设备”能够继续使用,TLS 1.3不得不做出妥协,通过“伪装”实现兼容:保持现有的记录格式不变,让TLS 1.3看起来像TLS 1.2。
扩展协议
那么,如何区分1.2和1.3呢?
这里使用了一个新的扩展协议,意思是“补充条款”。通过在记录的末尾添加一系列“扩展字段”,可以添加新的功能。旧版TLS不知道就可以直接忽略,实现了“向后兼容”。
TLS 1.3通过扩展实现了很多重要的功能,如“supported _ groups”、“key _ share”、“signature _ algorithms”、“server _ name”等。
TLS 1.2,在十几年的实践中获得了很多宝贵的经验,发现了很多加密算法的漏洞和弱点。因此,消除潜在危险的设计以纠正之前的错误,就成为了TLS 1.3的设计目标之一。所以这些不安全因素应该在新版TLS协议中得到修正。
例如:
固定密钥交换
经过这次“瘦身”,TLS 1.3的密钥交换算法只有ECDHE和DHE,椭圆曲线(ECC)也被“切割”到只有P-256和x25519。
首先说一下废除RSA和DH密钥交换算法的原因:
因为客户端会默认选择ECDHE而不是RSA作为密钥交换,这是因为它不具备“前向保密性”:“如果有人长时间记录加密数据,然后在随后的一段时间内获得服务器的RSA私钥,那么黑客就可以用这个私钥解密之前所有消息的“预主”,然后计算出会话密钥来破解所有密文。这是今天拦截,明天破解。”
ECDHE算法每次握手都生成一对临时公钥和私钥,每次通信的密钥对都不一样,即“一次一密”。即使黑客这次花大力气破解了会话密钥,也只是这次通信被攻击,之前的历史消息不会受到影响,仍然是安全的。
因此,主流的服务器和客户端在握手阶段不再使用RSA,而是使用ECDHE,而TLS 1.3在协议中明确废除了RSA和DH,在标准层面上保证了“前向安全性”。
固定密码
多年来,密钥交换机制并不是唯一造成安全漏洞的部分,对称密钥部分也存在相当多的问题。
同样,对称加密算法瘦身后只保留AES和ChaCha20,分组方式只能用AEAD的GCM、CCM和Poly1305,摘要算法只能用SHA 256和SHA 384。
这样,许多加密算法和参数组合使得密码套件非常复杂,难以选择。瘦身后,TLS 1.3只剩下5个套件,让客户端或服务器选择密码套件变得“更容易”。然而更重要的是,这些算法在TLS的长期实践中被证明是不安全因素,导致了安全漏洞。
修复数字签名
经过前面的学习,相信你也知道TLS的另一个重要部分是认证。在每个连接中,该服务使用带有公钥的数字证书向客户端提供身份验证。在RSA加密模式下,服务器通过解密预主密钥,并通过会话记录计算MAC,证明自己对私钥的所有权。在Diffie-Hellman模式下,服务器使用数字签名来证明私钥的所有权。
在TLS 1.2及更早的版本中,服务器的签名只覆盖握手的一部分。用于协商使用哪个对称密码的部分不是由私钥签名的。这也导致了很多引人注目的漏洞,比如怪胎,僵局等等。在TLS 1.3中,因为服务器对整个握手记录进行签名,所以可以避免这些情况。
建立连接时,HTTPS不仅要进行TCP握手,还要进行TLS握手。在TLS 1.2中,会多两次消息往返(2-RTT),可能会造成几十毫秒甚至几百毫秒的延迟,在移动网络中延迟会更严重。
1-RTT模式
密码套件大大简化,不用再像以前一样经历复杂的协商过程。TLS 1.3压缩了之前的“Hello”协商过程,删除了“密钥交换”消息,将抓取时间缩减为“1-RTT”,效率翻倍。
以下是TLS 1.3握手过程示意图。注意前面介绍的TLS 1.2的区别。
0-RTT恢复
除了标准的“1-RTT”握手之外,受QUIC协议的启发,客户端可以在第一条消息中向服务器发送加密数据,这与未加密的HTTP相比没有额外的延迟成本。
在TLS 1.2中,有两种恢复连接的方法:会话ID和会话票证,而1.3将它们结合起来,形成了一种新的模式,称为PSK(预共享密钥)恢复。
握手分析
目前Nginx等Web服务器可以很好的支持TLS 1.3,但是底层OpenSSL必须是1.1.1。所以如果要部署,需要先升级你的OpenSSL版本。
首先,TCP建立连接后,浏览器先发送一个“客户端你好”。
由于1.3的报文兼容1.2,所以初始版本号、支持的密码套件、客户端随机数结构都是一样的(此时的随机数为32字节)。
注意“客户端你好”中的扩展,“supported_versions”表示这是TLS 1.3,“supported_groups”是被支持的曲线,“key_share”是曲线对应的参数。
这有点像“尽量一口气把要说的话说完”或者像往常一样“打个招呼”。我这里有这个资料,所以考虑到版本升级,我附上一些资料,以后可能会用到。
当服务器收到“客户端你好”的消息时,也返回“服务器你好”的消息,或者应该给出一个随机数(服务器随机)和选择的密码套件。
表面上看,版本和TLS 1.2是一样的,重点是后期的扩展。确认“supported_versions”中使用了TLS 1.3,然后将曲线和对应的公钥参数放在“key_share”扩展上。
服务器的响应还是和老套路一样。服务器选择客户端提供的信息,此外,服务器还必须附加一些参数。这种加密是通过协商解决的。
可以看出,与TLS 1.2的握手过程相比,TLS 1.3只使用了两个消息来享受四个消息:客户端随机和服务器随机,客户端参数和服务器参数。双方都可以由DH计算“预主”,再由HKDF生成“主密”,比TLS 1.2效率高很多。
服务器计算出主密钥后,立即发出“更改Crypter Spec”消息,比TLS 1.2更早进入加密通信,后续证书全部加密,减少握手时明文信息泄露。
TLS 1.3还增加了一个消息“更改密码规范”,服务器用私钥对曲线、套件、参数等握手数据进行签名,类似于消息“完成”。但由于是私钥签名,加强了身份认证和防篡改。
两次“hello”消息后,客户端验证服务器证书,然后发送“完成”消息,正式完成握手,开始收发HTTP消息。
现在有很多网站支持TLS 1.3,比如GitHub:
今天主要介绍TLS 1.3的一些新特性,可以总结如下:
TLS 1.3涉及的内容很多。请参考RFC-8446,了解更多详细信息。关于这部分你还有什么想分享的?欢迎大家留言或者指正。
网络安全系列主题
延伸阅读