TLS 1.3 在握手效率和安全机制上做了重大改进。除了优化的握手流程外,协议还定义了一系列 Post-Handshake 消息,在握手完成后处理会话恢复、密钥更新等重要功能。理解这些消息对于深入掌握 TLS 1.3 至关重要。
什么是 Post-Handshake 消息?#
在 TLS 1.3 中,握手完成后双方进入加密通信阶段。此时协议定义了一组特殊消息,用于处理握手后的事务:
- NewSessionTicket:发送会话票据,用于后续会话恢复
- KeyUpdate:更新加密密钥,保持前向安全性
- CertificateRequest:请求客户端证书(握手后认证)
- Certificate:提供客户端证书
- CertificateVerify:验证客户端证书
这些消息与主握手流程独立,通过独立的加密通道传输。
NewSessionTicket(会话票据)#
NewSessionTicket 是 TLS 1.3 会话恢复机制的核心。当客户端和服务器完成完整握手后,服务器可以发送一个加密的会话票据给客户端。下次连接时,客户端可以使用这个票据恢复会话,无需完整握手,从而实现 1-RTT 甚至 0-RTT 的快速连接。
工作流程#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
完整握手:
客户端 服务器
| |
|--------------- ClientHello ----------------->|
| (附 session_id / session_ticket) |
|<-------------- ServerHello ------------------|
|<-------------- Certificate ------------------|
|<-------------- CertificateVerify ------------|
|<---------------- Finished -------------------|
|--------------- Finished -------------------->|
| |
|================ 加密通道 ====================|
| |
|<------------- NewSessionTicket -------------|
| |
快速恢复(0-RTT):
客户端 服务器
| |
|-------- ClientHello + EarlyData + Ticket -->|
|<-------- ServerHello + EarlyData ------------|
|<---------------- Finished -------------------|
|--------------- Finished -------------------->|
| |
|
实际验证#
使用 OpenSSL 查看 TLS 1.3 会话恢复:
1
2
3
|
# 查看 TLS 1.3 连接(会话票据默认启用)
$ echo | openssl s_client -connect cloudflare.com:443 -tls1_3 2>&1 | grep -E "Protocol|Cipher"
New, TLSv1.3, Cipher is TLS_CHACHA20_POLY1305_SHA256
|
查看会话恢复过程(-reconnect 使用相同会话ID重新连接):
1
2
3
4
5
|
# 第一次连接后,使用 -reconnect 测试会话恢复
$ openssl s_client -connect cloudflare.com:443 -tls1_3 -reconnect 2>&1 | grep -E "Protocol|Cipher"
New, TLSv1.3, Cipher is TLS_CHACHA20_POLY1305_SHA256
New, TLSv1.3, Cipher is TLS_CHACHA20_POLY1305_SHA256
New, TLSv1.3, Cipher is TLS_CHACHA20_POLY1305_SHA256
|
可以看到多次连接的 Cipher 相同,说明会话票据恢复成功。
票据生命周期#
会话票据包含时间戳信息,过期后无法使用:
1
2
|
# 解密会话票据(需要服务器密钥)
# 注意:客户端无法直接解密票据,这是服务器的责任
|
安全考虑#
- 前向安全性:会话票据使用会话密钥加密,该密钥从主密钥派生
- 票据有效期:服务器应设置合理的票据 lifetime,通常为数小时到数天
- 0-RTT 风险:使用 0-RTT 数据可能面临重放攻击风险
KeyUpdate(密钥更新)#
TLS 1.3 允许在握手完成后动态更新加密密钥,无需重新握手。这通过 KeyUpdate 消息实现,详细机制在 TLS 1.3 密钥更新机制解析 中已有讲解。
核心要点:
- 使用 HKDF 从当前密钥派生出新密钥
- 可以单向或双向更新
- 开销极低,仅需传输几字节
Post-Handshake Authentication(握手后认证)#
TLS 1.3 引入了灵活的握手后认证机制,允许服务器在握手完成后请求客户端证书。
传统的 TLS 握手要求客户端证书在主握手阶段提供。TLS 1.3 支持 延迟认证:先完成握手建立加密通道,然后在需要时请求客户端证书。
工作流程#
1
2
3
4
5
6
7
8
9
10
11
|
正常握手完成后(已加密通道):
客户端 服务器
| |
|<---------- CertificateRequest --------------|
| (请求客户端证书) |
| |
|----------- Certificate ---------------------|
|----------- CertificateVerify --------------->
| |
|------------ Finished ---------------------->|
| |
|
实际验证#
配置 Nginx 要求客户端证书:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/server.crt;
ssl_certificate_key /path/to/server.key;
# 启用 TLS 1.3
ssl_protocols TLSv1.3;
# 要求客户端证书(握手后认证)
ssl_verify_client on;
# 客户端证书颁发机构
ssl_client_certificate /path/to/ca.crt;
}
|
使用 OpenSSL 测试:
1
2
3
4
5
6
7
8
|
# 使用客户端证书连接
$ openssl s_client -connect example.com:443 -tls1_3 \
-cert /path/to/client.crt -key /path/to/client.key
# 查看连接信息
$ openssl s_client -connect example.com:443 -tls1_3 \
-cert /path/to/client.crt -key /path/to/client.key 2>&1 | \
grep -E "Client Certificate|Verify Return"
|
与 TLS 1.2 的区别#
| 特性 |
TLS 1.2 |
TLS 1.3 |
| 客户端证书时机 |
握手期间 |
握手后(可选) |
| 认证灵活性 |
固定 |
可选、按需 |
| 0-RTT 支持 |
无 |
支持 |
消息类型识别#
TLS 1.3 Post-Handshake 消息通过 Content Type 区分:
| Content Type |
消息类型 |
| 20 |
KeyUpdate |
| 21 |
NewSessionTicket |
| 22 |
CertificateRequest |
| 23 |
Certificate |
| 24 |
CertificateVerify |
| 25 |
Finished |
可以通过 Wireshark 观察这些消息:
1
2
3
|
# Wireshark 过滤器
tls.record.content_type == 20 # KeyUpdate
tls.record.content_type == 21 # NewSessionTicket
|
实际应用建议#
1. 会话恢复配置#
1
2
3
|
# Nginx 配置会话票据
ssl_sessionTickets on;
ssl_session_timeout 1d;
|
2. 密钥更新策略#
大多数服务器自动处理密钥更新,无需手动配置。如需自定义:
1
2
3
|
# Nginx TLS 1.3 配置
ssl_protocols TLSv1.3;
ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
|
3. 客户端认证策略#
根据业务需求选择认证时机:
- 高安全要求:握手期间认证(传统方式)
- 灵活认证:握手后认证(TLS 1.3)
TLS 1.3 的 Post-Handshake 消息机制提供了强大的功能:
- NewSessionTicket:实现高效的会话恢复,减少延迟
- KeyUpdate:保持前向安全性,无需完整握手
- Post-handshake Auth:灵活的客户端认证机制
这些机制共同使 TLS 1.3 成为一个高效、安全、易用的协议。在实际部署中,正确配置这些特性可以显著提升用户体验和安全性。
参考来源#