主要讲加密算法RSA,ECDHE
TLS的握手涉及四次通信,根据不同的密钥交换算法,TLS 握手流程也会不一样的,现在常用的密钥交换算法有两种:RSA 算法和 ECDHE 算法
正常情况下,需要先TCP三次握手后进行TLS四次握手
「TCP Fast Open + TLSv1.3 + 第二次以后的通信」情况下,TLS 和 TCP 的握手过程是可以同时进行的;且会话复用可以做到0-RTT
RSA握手:
1.ClientHello
客户端发送 ClientHello 消息,包含支持的 TLS 版本、加密套件列表、随机数(后面用于生成「会话秘钥」条件之一)
2.SeverHello
服务器响应 ServerHello 消息,选择 TLS 版本和加密套件RSA,并发送自己的随机数(也是后面用于生产「会话秘钥」条件之一)。
- 服务器的数字证书Certificate(单独发送的消息)
3.Client Key Exchange
证书验证:
客户端在收到服务器的 ServerHello 和数字证书后,首先会通过操作系统或浏览器中的 CA 公钥验证服务器的证书的真实性。如果证书有效,客户端可以信任该服务器。
公钥提取:
客户端从验证过的数字证书中提取服务器的公钥。
生成 Pre-Master key ( 预主密钥**)** 并 加密和发送:
客户端生成一个新的随机数,称为 pre-master key(后面用于生成「会话秘钥」条件之一),并且用公钥加密发送
服务器和客户端有了这三个随机数(Client Random、Server Random、pre-master key),接着就用双方协商的加密算法,各自生成本次通信的「会话秘钥」。
接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用「会话秘钥」加密内容。
RSA缺陷:
随机数的交换是使用服务端公钥加密的,如果服务端私钥泄露,就会被第三方截取所有的密文
RSA没实现前向保密的原因:长期密钥的使用、缺乏临时密钥机制
ECDHE握手:
1.Client Hello
客户端发送 ClientHello 消息,包含支持的 TLS 版本、加密套件列表、随机数(后面用于生成「会话秘钥」条件之一
2.Server Hello
- 服务器响应 ServerHello 消息,选择 TLS 版本和加密套件ECDHE,并发送自己的随机数(也是后面用于生产「会话秘钥」条件之一)
- 发送 证书Certificate 给客户端
- 因为服务端选择了 ECDHE 密钥协商算法,所以会在发送完证书后,发送 Server Key Exchange 消息。
- 选择椭圆曲线和基点G
- 生成随机数作为服务端私钥 d1,保存在本地
- 生成公钥 Q1 ( Q1 = d1G**)**,发送给客户端,为了保证这个椭圆曲线的公钥不被第三方篡改,服务端会用 RSA 签名算法给服务端的椭圆曲线公钥做个签名
3.Client Key Exchange
- 根据证书验证服务端身份,生成一个随机数作为客户端椭圆曲线的私钥 d2 ,然后再根据服务端选的基点G,生成客户端的椭圆曲线公钥 Q2,然后用 Client Key Exchange 消息发Q2给服务端。
- 至此,双方都有对方的椭圆曲线公钥、自己随机生成的的椭圆曲线私钥、椭圆曲线基点 G。于是,双方都就计算出点(x,y),其中 x 坐标值双方都是一样的,前面说 ECDHE 算法时候,说 x 是会话密钥,但实际应用中,x 还不是最终的会话密钥。
- 最终的会话密钥,是用 客户端随机数 + 服务端随机数 + ECDHE 算法算出的共享密钥 X 三个材料生成的。保证安全可靠
于是,就可以正常收发加密的 HTTP 请求和响应了
ECDHE 密钥交换可以将TLS 握手减少到 1 RTT。客户端在收到服务器的 Server Hello 和证书后,可以直接计算共享密钥并发送加密的握手消息,不再需要额外的往返时间。
前向保密的实现
- 临时性:由于每次握手都生成新的临时密钥,即使长期私钥被泄露,攻击者也无法使用它解密过去的会话,因为每个会话的会话密钥是独立的。
- 密钥的分离:会话密钥的生成依赖于临时密钥和随机数,而不是长期密钥。这样,即使长期密钥被攻击者获取,之前的会话密钥仍然无法被恢复。