为什么要了解消息加密时机#
在调试TLS问题时,一个常见的困惑是:握手过程中的消息,哪些是加密的,哪些是明文传输的?
理解这个问题对于:
- 诊断TLS握手故障
- 使用Wireshark等工具分析流量
- 理解TLS的安全边界
都非常重要。
TLS 1.2 握手消息加密顺序#
在TLS 1.2中,握手消息的加密并不是从一开始就开始的。让我们按顺序来看:
明文消息(不加密)#
以下消息在握手初期以明文传输:
1
2
3
4
5
6
7
|
1. ClientHello → 明文
2. ServerHello → 明文
3. Certificate → 明文
4. ServerKeyExchange → 明文
5. ServerHelloDone → 明文
6. ClientKeyExchange → 明文
7. ChangeCipherSpec → 明文
|
关键点:这些消息使用明文发送,因为此时双方还没有协商出加密密钥。
加密消息#
从ChangeCipherSpec之后,所有的握手消息都被加密:
1
2
|
8. Finished → 加密
9. (后续应用数据) → 加密
|
完整流程图#
1
2
3
4
5
6
7
8
9
10
11
12
13
|
客户端 服务器
| |
|------------------- ClientHello (明文) ------------→|
|←---------------- ServerHello (明文) ---------------|
|←---------------- Certificate (明文) ---------------|
|←---------------- ServerKeyExchange (明文) ---------|
|←---------------- ServerHelloDone (明文) -----------|
|----------------- ClientKeyExchange (明文) --------→|
|----------------- ChangeCipherSpec (明文) --------→|
|----------------- Finished (加密) ----------------→|
|←---------------- ChangeCipherSpec (明文) ----------|
|←---------------- Finished (加密) -----------------|
|================= 应用数据 (加密) =================|
|
注意:虽然ChangeCipherSpec消息本身是明文,但它是一个切换通知,告诉对方"接下来的消息将使用协商的加密套件"。
TLS 1.3 握手消息加密顺序#
TLS 1.3对握手进行了重大简化,消息加密时机也有所不同。
1-RTT握手加密流程#
1
2
3
4
5
6
7
8
9
10
|
客户端 服务器
| |
|------------------- ClientHello (明文) ------------→|
|←---------------- ServerHello (加密) --------------|
|←---------------- EncryptedExtensions (加密) ------|
|←---------------- Certificate (加密) --------------|
|←---------------- CertificateVerify (加密) --------|
|←---------------- Finished (加密) -----------------|
|----------------- Finished (加密) ----------------→|
|================= 应用数据 (加密) =================|
|
关键区别#
TLS 1.3的重要改进:从ServerHello开始,消息就已经被加密了!
这是因为TLS 1.3使用了**前向安全(Forward Secrecy)**的密钥交换方式(ECDHE),双方可以在ClientHello和ServerHello过程中快速生成临时密钥。
0-RTT早期数据(可选)#
TLS 1.3还支持0-RTT模式,允许在握手之前发送加密数据:
1
2
3
4
5
6
|
客户端 服务器
| |
|------------------- ClientHello (明文) ------------→|
|------------------- EarlyData (加密) ------------→| ← 可选,早期数据
|←---------------- ServerHello (加密) --------------|
...
|
安全注意:0-RTT数据缺乏前向安全性,存在重放攻击风险。
对比总结#
| 握手阶段 |
TLS 1.2 |
TLS 1.3 |
| ClientHello |
明文 |
明文 |
| ServerHello |
明文 |
加密 |
| 证书 |
明文 |
加密 |
| 密钥交换 |
明文 |
加密(通过ECDHE) |
| Finished |
加密 |
加密 |
实际影响#
1. Wireshark抓包分析#
在TLS 1.2中,你可以在Wireshark中看到明文的握手消息:
1
2
3
4
|
TLS 1.2 ClientHello (明文可见)
TLS 1.2 ServerHello (明文可见)
TLS 1.2 Certificate (明文可见)
...
|
在TLS 1.3中,只有ClientHello是明文:
1
2
3
|
TLS 1.3 ClientHello (明文可见)
TLS 1.3 ServerHello (加密,需密钥解密)
...
|
2. 调试技巧#
使用OpenSSL查看握手消息:
1
2
3
4
5
6
7
8
|
# 查看TLS 1.2握手消息(-msg显示详细信息)
openssl s_client -connect example.com:443 -tls1_2 -msg
# 查看TLS 1.3握手消息
openssl s_client -connect example.com:443 -tls1_3 -msg
# 同时显示十六进制内容
openssl s_client -connect example.com:443 -tls1_3 -msg -debug
|
3. 安全边界理解#
- TLS 1.2:证书等信息以明文传输,理论上可被中间人查看(但不能篡改)
- TLS 1.3:更多握手信息被加密,减少了信息泄露风险
常见问题#
Q: ChangeCipherSpec是加密的吗?#
A: 在TLS 1.2中,ChangeCipherSpec本身是明文消息,但它是一个状态切换标志。在TLS 1.3中,ChangeCipherSpec被移除,相关功能整合到握手消息中。
Q: 为什么TLS 1.3可以从ServerHello开始加密?#
A: TLS 1.3强制使用ECDHE(椭圆曲线Diffie-Hellman)密钥交换。客户端在ClientHello中包含自己的DH公钥,服务器在ServerHello中回复DH公钥,双方可以立即计算出共享密钥,从而实现从ServerHello开始的加密。
Q: 如何确认握手消息是否加密?#
A: 可以通过Wireshark观察:
- 观察TLS Record Layer的Content Type
- 明文消息通常是handshake (0x16)
- 加密消息通常是application_data (0x17)
理解TLS握手消息的加密时机,有助于:
- 调试问题:知道哪些信息可以看到,哪些看不到
- 安全评估:理解TLS的安全边界
- 工具使用:更有效地使用Wireshark等分析工具
TLS 1.3在安全性上的一个重要改进,就是从ServerHello开始就使用加密,大幅减少了握手过程中的信息泄露。
参考来源#