Web技术(四):TLS 握手过程与性能优化(TLS 1.2与TLS 1.3对比)_流云IoT的博客-CSDN博客_tls1.2握手过程
一 TLS发展历史:
SSL(Secure Socket Layer) / TLS(Transport Layer Security) 是独立于 HTTP 的协议,所以不光是 HTTP 协议,其他运行在应用层的 SMTP 和 Telnet 等协议均可配合 SSL / TLS 协议使用,可以说 SSL / TLS 是当今世界上应用最为广泛的网络安全技术。
Netscape 开发了原始的 SSL 协议:
TLS的发展历程:
二 TLS1.2 和 TLS1.3的主要差别:
三 TLS1.2 和 TLS1.3的握手流程:
TLS1.2 的握手流程:
TLS 1.2 完整的握手过程(从发送第一个握手报文到发送第一个用户数据报文)需要在客户端与服务器之间完成两次往返通信,也即 2-RTT(Round Trip Time)
TLS 1.2 会快速恢复的过程
TLS 1.2 会话恢复的简短握手过程从发送第一个报文ClientHello到发送应用数据,只需要一次网络往返 1-RTT
利用session-id恢复的缺点:
为了解决使用Session ID的问题,又引入了Session Ticket 作为新的会话恢复方案。
TLS1.3 的握手流程:
LS 1.3 废弃了RSA密钥交换方案(因为RSA不具有前向保密性),仅支持(EC)DHE密钥协商方案;
TLS 1.3 可以在第一个网络往返中完成共享密钥协商和身份认证,在完成共享密钥协商和身份认证后可以直接切换到应用数据协议,所以TLS 1.3 完整握手过程只需要一个网络往返(1-RTT)。
TLS 1.3 完整握手过程图示如下:
从TLS 1.3 的握手过程可以看出;
Halfrost-Field/TLS_1.3_Handshake_Protocol.md at master · halfrost/Halfrost-Field · GitHub
struct {
NamedGroup group; //有限域参数组或椭圆曲线类型
opaque key_exchange<1..2^16-1>; // 密钥协商参数
} KeyShareEntry;
// 下面每一个名称对应一个确定的椭圆曲线或一组确定的有限域参数,按优先级从高到低排列,由
ClientHello报文的Extension - Supported Groups扩展字段记录这些用于密钥交换的命名组
enum {
/* Elliptic Curve Groups (ECDHE) */
secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019),
x25519(0x001D), x448(0x001E),
/* Finite Field Groups (DHE) */
ffdhe2048(0x0100), ffdhe3072(0x0101), ffdhe4096(0x0102),
ffdhe6144(0x0103), ffdhe8192(0x0104),
/* Reserved Code Points */
ffdhe_private_use(0x01FC..0x01FF),
ecdhe_private_use(0xFE00..0xFEFF),
(0xFFFF)
} NamedGroup;
TLS 1.3握手报文ClientHello与ServeHello在进行密钥协商时并没有进行数字签名,通信双方的身份认证主要靠后续的Certificate与CertificateVerify报文保证,因为CertificateVerify报文是对之前的握手消息(自然包括密钥协商消息)进行签名,身份认证放到后面也不会影响整个握手过程的安全性。把客户端与服务器之间完整握手过程中每个握手报文的作用及传递的主要参数字段展开,如下图所示:
TLS 1.3 会话恢复 0-RTT 的简短握手
TLS 1.3 采用了新的会话缓存恢复方案 — PSK (pre_shared_key)握手,该方案相当于TLS 1.2 Session Ticket 会话恢复方案的升级版。
TLS 1.3 完整握手过程ClientHello报文中出现的两个扩展字段psk_key_exchange_modes和pre_shared_key,PSK会话缓存恢复方案正需要借助这两个字段:
字段名 | 作用 |
---|---|
psk_key_exchange_modes |
从PSK建立主密钥的模式有两种,该字段可能的取值也有两种: 1. psk_ke:仅使用PSK建立主密钥,Server 不提供key_share 值(0-RTT); 2. psk_dhe_ke:使用PSK 和 (EC)DHE 建立主密钥,Client 和 Server 必须提供key_share 值(1-RTT)。 |
pre_shared_key (PSK) | 预共享密钥标识,也即"New Session Ticket + Binders",New Session Ticket 包含PSK初始值、名称、有效期等信息,Binders 包含PSK与当前握手的绑定信息 |
early_data |
当通信双方有预共享密钥 PSK 时,TLS 1.3 允许在ClientHello报文的扩展字段 early data 中携带应用数据(携带数据量不超过max_early_data_size值),early_data中的应用数据使用PSK 生成的early_secret 加密。 |
EndOfEarlyData | 如果在ClientHello报文中发送了early_data,在收到Server_Finished报文后发送EndOfEarlyData报文,表示已传输完了所有 0-RTT application_data 消息,并且接下来的application_data 消息使用新的密钥application_secret 加密 |
TLS 1.3 完成完整握手过程后,服务器也会生成一个 New Session Ticket 并发送给客户端保存。New Session Ticket 中包含恢复共享密钥、有效期、随机数nonce等信息,可以使用New Session Ticket 中的信息生成预共享密钥PSK,过程大概如下:
struct {
uint32 ticket_lifetime;
uint32 ticket_age_add;
opaque ticket_nonce<0..255>;
opaque ticket<1..2^16-1>;
Extension extensions<0..2^16-2>;
} NewSessionTicket;
// 通过HKDF生成预共享密钥PSK,resumption_master_secret是在完整握手过程随主密钥
一起生成的
// ticket_nonce对于每个NewSessionTicket都是不同的,保证不同的NewSessionTicket
生成不同的PSK
PSK = HKDF-Expand-Label(resumption_master_secret,
"resumption", ticket_nonce, Hash.length)
从上图TLS 1.3 会话恢复简短握手过程可以看出,发送首个报文ClientHello时就可以通过early_data 发送应用数据,因此从发送首个报文到发送应用数据之间并没有经过网络往返,也即0-RTT。因为发送early_data 不依赖ServerHello消息,安全性自然更弱一些,如果攻击者捕获发送到服务器的 0-RTT 数据包,他们可以重播该数据包,并且服务器可能会接受该数据包为有效数据包,甚至借此改变服务器上的重要资源状态,这就是 0-RTT 重放攻击:
为了应对 0-RTT 攻击,一般会限制 0-RTT 会话恢复的使用范围,比如在 0-RTT 中发送不改变服务器资源状态的HTTP GET报文等。TLS 1.3 会话恢复简短握手过程完成后,用于加密应用数据的密钥是双方再计算出来的密钥,包含了双方随机数或握手报文散列值信息,保证每次会话尽可能使用一次性密钥,同时也具备前向保密性。