“
字节面试官:TLS 三个版本的握手方式,你都了解吗?
”
TLS 握手的过程比较复杂,就如上面的问题,我之前的理解很是零碎,面试时回答地并不好。现在闲下来,写下此文加深理解。
具体梳理如下:
- TLS 的历史。
- 各版本的握手细节与总结。
- 扩展。
SSL/TLS 历史
我们知道,HTTP 是明文传输的协议,可能受到第三方的攻击,非常不安全。因此才诞生 “HTTPS”。
这个 “S” 表示 SSL/TLS 协议,用公式说明:HTTPS = HTTP + SSL(TLS)。
其中 SSL 即安全套接层(Secure Sockets Layer),处于 OSI 七层模型中的会话层。
带有 TLS 安全协议的网站,如 掘金 在 Chrome 浏览器地址栏上会将 https/www
等自动隐藏,以 🔐 代之:
以下是权威文档摘取的部分历史:
-
1996 年,SSL3.0 问世,得到大规模应用(已于 2015 年弃用)。
-
1999 年,SSL3.1 被标准化,更新为 TLS1.0(传输层安全,Transport Layer Security)。所以有,TLS1.0 = SSL3.1。
-
现在主流的版本是 TLS1.2(2008 年发布)。
-
未来,可能是 TLS1.3 的时代(2018 年发布)。
TLS 握手
要了解具体的握手流程,首先我们要了解何为握手?
握手 (Handshake)
:一般是通信的前置动作,即达成某种约定,比如 TCP 握手是要确定双端的接收、发送能力等;而 TLS 握手则是为了验证身份、交换信息从而生成秘钥,为后续加密通信做准备。
通过 Wireshark 抓包我们不难发现:不论客户端和服务端的连接走 HTTP 还是 TLS 协议,所有连接最初都要经过 TCP 三次握手,而 TLS 四次握手是在 TCP 建立连接之后进行的。
因此,HTTPS 首次通信需要 7 次握手!
详细的 TCP 学习资料可以查阅这里:TCP灵魂之问,不是本节的重点。
本节将会解析 TLS 主要的两种握手方式,分别为:RSA 握手
、DH 握手
。再以 DH 握手
为基础继续演进优化,推出更安全、性能更佳的 TLS1.3
版本握手方式。不过在此之前,还需要了解一些基础概念 (若已了解可跳过)。
基础概念
① 对称加密
加、解密使用的同一串密钥,常见的对称加密算法:DES,AES 等。
② 非对称加密
加、解密使用不同的密钥,一把作为公开的公钥,另一把作为保密的私钥。公钥加密的信息,只有私钥才能解密。反之,私钥加密的信息,只有公钥才能解密。
常见的非对称加密算法:RSA,ECC 等。
RSA 算法:该算法的命名以三位科学家的姓氏缩写组合得来,在计算机网络世界,一直是最广为使用的 “非对称加密算法”。
ECC 是非对称加密里的 “后起之秀”,它基于 “椭圆曲线离散对数” 的数学难题,使用特定的曲线方程和基点生成公钥和私钥,子算法 ECDHE 用于密钥交换,ECDSA 用于数字签名。
③ 混合加密
在 对称加密
算法中只要持有密钥就可以解密。如果你和网站约定的密钥在传递途中被黑客窃取,那他就可以在之后随意解密收发的数据,通信过程也就没有机密性可言了。
在 非对称加密
算法中,需要应用到复杂的数学运算,虽然保证了安全,但速度很慢,比对称加密算法差了好几个数量级。
所以,TLS 里使用了 “混合加密” 的方式博采众长:在通信刚开始的时候使用 非对称加密
算法,解决密钥交换的问题。后续全都使用 对称加密
进行通信。
加密套件列表
加密套件列表一般由客户端发送,供服务器选择。用 openssl 查看列表:
➜ openssl ciphers -v
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
AES256-SHA256 TLSv1.2 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA256
...
... Cipher Suites(17 suites)
上图数据表明列表附带了多达 17 个加密套件,单个拎出来一般长这样:
意思是:
TLS
握手过程中,使用ECDHE
算法生成 pre_random。- 身份验证 (签名) 使用
RSA
算法。 - 128 位的
AES
算法进行对称加密,在对称加密的过程中使用主流的GCM
分组模式,可以让算法用固定长度的密钥加密任意长度的明文。 - 最后是用于数据完整性校验的哈希摘要算法,采用
SHA256
算法。
数字证书
数字证书一般有两个作用:
- 服务器向浏览器证明自己的身份,毕竟秘钥、甚至服务器域名都是可以伪造的。
- 把公钥传给浏览器。
证书本身是由权威、受信任的证书颁发机构 (CA) 授予的。
RSA 握手
先看图
具体流程如下:
1.浏览器向服务器发送随机数 client_random,TLS 版本和供筛选的加密套件列表。
2.服务器接收到,立即返回 server_random,确认好双方都支持的加密套件
以及数字证书 (证书中附带公钥 Public key certificate)。
3.浏览器接收,先验证数字证书。若通过,接着使用加密套件的密钥协商算法 RSA
算法生成另一个随机数 pre_random,并且用证书里的公钥加密,传给服务器。
4.服务器用私钥解密这个被加密后的 pre_random,参考 “非对称加密”。
现在浏览器和服务器都拥有三样相同的凭证:client_random、server_random 和 pre_random。两者都用筛好的加密套件中的加密方法混合这三个随机数,生成最终的密钥。
最后,浏览器和服务器使用相同的密钥进行通信,即使用 对称加密
。
到这里,还有两点需要注意。
第一:握手中的任何消息均未使用秘钥加密,它们都是明文发送的。
第二:TLS 握手其实是一个 双向认证
的过程,客户端和服务器都需要进行摘要认证以及收尾 (发送 Finished 消息,意为后面 HTTP 开始正式加密报文通信了)。
DH 握手
还是看图:
具体流程如下(放出 diff 比较):
1.浏览器向服务器发送随机数 client_random,TLS 版本和供筛选的加密套件列表。
// RSA
-2.服务器接收到,立即返回 server_random,确认好双方都支持的加密套件
-以及数字证书 (证书中附带公钥)。
// DH
+2.服务器接收到,立即返回 server_random,确认好双方都支持的加密套件
+以及数字证书 (证书中附带公钥)。
+同时服务器利用私钥将 client_random,server_random,server_params 签名,
+生成服务器签名。然后将签名和 server_params 也发送给客户端。
+这里的 server_params 为 DH 算法所需参数。
// RSA
-3.浏览器接收,先验证数字证书。
-若通过,接着使用加密套件的密钥协商算法 RSA 算法
-生成另一个随机数 pre_random,并且用证书里的公钥加密,传给服务器。
// DH
+3.浏览器接收,先验证数字证书和 _签名_。
+若通过,将 client_params 传递给服务器。
+这里的 client_params 为 DH 算法所需参数。
-4.服务器用私钥解密这个被加密后的 pre_random,参考 “非对称加密”。
+4.现在客户端和服务器都有 client_params、server_params 两个参数,
+因 ECDHE 计算基于 “椭圆曲线离散对数”,通过这两个 DH 参数就能计算出 pre_random。
现在浏览器和服务器都拥有三样相同的凭证:client_random、server_random 和 pre_random,后续步骤与 RSA 握手一致。
DH 握手前向安全性
TLS1.2 握手
有了前面一节的概念后,TLS1.2 握手理解起来就显得毫不费力了。因为主流的 TLS1.2 握手就是上节完整的 DH 握手流程。
TLS1.3 握手
互联网的世界飞速发展,随着时间的推移,人们早已不满足于现有的 TLS1.2。于是,更快、更安全的 “船新版本” TLS1.3 发布了。
TLS1.3 废除了原有的部分不安全的加密算法,其中甚至包括 RSA
算法。
RSA 算法的废除不仅因为已经有大能将其激活成功教程,同时还缺少 前向安全性
。何为前向安全?即能够保护过去进行的通讯不受密码或密钥在未来暴露的威胁。
现在我们来看看 TLS1.3 握手具体流程,先放图:
流程梳理:
// 原 DH 握手
-1.浏览器向服务器发送 client_random,TLS 版本和供筛选的加密套件列表。
// TLS1.3 优化
+1.浏览器向服务器发送 client_params,client_random,TLS 版本和供筛选的加密套件列表。
// 原 DH 握手
-2...
// TLS1.3 优化
+2.服务器返回:server_random、server_params、TLS 版本、确定的加密套件方法以及证书。
+浏览器接收,先验证数字证书和签名。
+现在双方都有 client_params、server_params,可以根据 ECDHE 计算出 pre_random 了。
最后,集齐三个参数,生成最终秘钥。
如你所见,TLS1.3 客户端和服务器之间只需要一次往返就完成 (TLS1.2 需要两次往返来完成握手),即 1-RTT
握手。当然,如果利用 PSK
我们甚至能优化到 0-RTT
(这并不好,安全受到质疑~)。
小结
以上,我们梳理了三个版本的 TLS 握手流程,它们其实属于两类:一种基于 RSA,另一种基于 Diffie-Hellman (ECDHE)。这两类握手的区别仅在于如何实现秘钥建立和身份验证:
秘钥交换 | 身份验证 | |
---|---|---|
RSA 握手 | RSA | RSA |
DH 握手 | ECDHE | RSA/DSA |
我们看到,在版本演进中,最新的 TLS1.3 抛弃了 RSA 算法是为了更安全,减少 RTT 是为了更快。可知,互联网技术革新的特点不外如是。
扩展
前文提到,握手是一个 双向认证
的过程,当然这并不绝对。
在握手的第三步,客户端验证证书的时候,如果服务端的证书在系统默认信任证书列表中则会直接通过,如果不在默认列表中,浏览器可能会弹窗让用户选择是否信任该证书,也有可能会直接关闭连接,提示证书不可信。
而在 App 内,如果想要信任未在系统信任列表中的证书,则需要在应用内提前置入服务端证书。此外,关于认证方式,大多数也都是采用的单向认证,也就是说仅仅认证服务端的证书,而像银行等机构则多使用双向认证的方式。
当然,握手的细节还有很多,由于篇幅原因,这里不再细讲,让我们回过头来,讲讲协议的核心之一:加密算法
。
大数据时代,需要收集大量的个人信息用于统计。
一方面它给我们带来了便利,与财富捆绑,如利用 哈希
算法的 区块链
。
另一方面一些个人信息数据在无意间被泄露,产生不良后果,就如某年的一起舆论自杀事故,被告人的个人数据在网络上爆发,再加上群众的盲目导向,最终导致被告人不堪精神压力酿成悲剧,而起因只是一件本可以轻易协商解决的事件。
这样的例子多不胜数,数据泄露的后果无法估量。
为了保护客户的隐私数据,不论是 HTTP 还是 HTTPS,都建议密文传输信息。当然数据加解密带来的性能消耗,也需要各位开发者各自衡量。
“
网络世界,越了解,便越敬畏。
”
最后
文章产出不易,还望各位小伙伴们支持一波!如有误,望指正。
往期精选:
参考资料
Keyless SSL: The Nitty Gritty Technical Details
The First Few Milliseconds of an TLS 1.2 Connection
TLS 1.3 Handshake: Taking a Closer Look
本文使用 mdnice 排版
今天的文章TLS 详解握手流程分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/19419.html