TLS1.3 通信流程梳理, 基本是从 https://tls13.xargs.org 翻译过来的, 建议看原文
记作 (client_priv, client_pub)
主要包含以下内容:
SNI 字段使服务器可以在同一个 ip:port 组上提供多个 TLS 服务, 在握手过程中根据 SNI 返回对应的证书。
Key Share 扩展会发送一个或多个客户端认为服务端很可能会接受的公钥及加密算法, 如果服务端接受, 则 Server Hello 后续的数据可以加密传输。相当于提前进行了 Key Exchange 如果服务端不能接受则返回一个 Retry Hello Request 消息重新进行握手。
Session Ticket 在连接建立完成后由服务端发送, 客户端可以保存此数据用于后续快速恢复重连。
PSK 的使用参考 When do clients use TLS in PSK mode?
记作 (server_priv, server_pub)
主要包含以下内容:
通过以下信息计算握手密钥:
后续的握手过程都通过此密钥加密
通过以下信息计算握手密钥:
后续的握手过程都通过此密钥加密
服务端根据 Client Hello 中指定的 SNI 返回证书并进行校验
某些情况下, 证书可能由二级 CA 颁发, 当客户端请求证书时, 服务端会将中间证书和自己的证书一并返回:
通过上一步, 客户端可以确认证书(包括其中的公钥)属于当前请求的服务名, 但还不能证明此服务器是此证书的所有者。因此服务端需要使用证书签发前创建的私钥 host_priv 加密握手消息摘要返回给客户端, 客户端可以根据证书 host_info 中的公钥 host_pub 解密此数据, 再自行计算握手消息摘要进行比对是否一致。至此客户端可以确认此连接的安全性
服务端将握手阶段的所有消息取哈希作为验证消息发送给客户端
服务端通过 Handshake Key 和从 Client Hello 到服务端握手结束的所有信息取哈希计算 Application Key 即后续数据传输阶段的对称密钥
客户端使用同样的方式计算 Application Key
客户端将握手阶段的所有消息取哈希作为验证消息发送给服务端
至此客户端和服务端之间可以通过 Application Key 进行对称加密通信
服务端为客户端提供 Session Ticket 用于后续快速开启新的会话, 减少会话创建阶段大量的计算和网络延迟。包括:
其中 Ticket Age Add
是由服务端生成的随机毫秒数, 客户端在使用 Session Ticket 恢复连接时需要将 ticket_age (表示从收到 Session Ticket 到目前当前的时间差) 加上此值进行混淆。服务端收到此值后校验客户端的 ticket_age 和自己计算的时间差是否接近, 如果超过了一定的阈值可以直接拒绝此连接。一定程度上避免了重用 Session Ticket 制造的重放攻击。
第二个 Session Ticket 由于客户端比如浏览器一般会发送多个连接, 且每个 Session Ticket 只能使用一次, 服务器一般会返回多个 Session Ticket
参考资料:
RFC8446
xargs.org - TLS
xargs.org - x25519
Wikipedia - Shared_secret
Wikipedia - Pre-shared_key
Wikipedia - SNI
A walkthrough of a TLS 1.3 handshake
一文详解 HTTPS 与 TLS证书链校验
SSL/TLS协议详解(中)——证书颁发机构
网络安全科普:奇妙的 SSL/TLS 证书(基础篇)