“
字节面试官: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
