网络安全 · 深度解析
HTTPS TLS
握手过程深度解析
从 TLS 1.2 的两次往返到 TLS 1.3 的一次往返 —— 理解现代 Web 安全基石的演进之路
TLS 1.0 ❌TLS 1.1 ❌TLS 1.2 ✅TLS 1.3 ✅ 推荐
握手流程
1-RTT(一次网络往返)更快
加密数据传输开始
RTT 对比示意
TLS 1.22-RTT
RTT 1 — 协商阶段
ClientHello →← ServerHello← Certificate← ServerKeyExchange← ServerHelloDone
RTT 2 — 密钥交换 + 完成
ClientKeyExchange →ChangeCipherSpec →Finished →← Finished
TLS 1.31-RTT
RTT 1 — 一次搞定!
ClientHello + KeyShare →← ServerHello + KeyShare← {EncryptedExtensions + Cert + Verify + Finished}Finished →
0-RTT 恢复(可选)有重放风险
ClientHello + EarlyData →← ServerHello + Finished
TLS 1.2 vs TLS 1.3
TLS 1.3 移除了什么?
TLS 1.3 大刀阔斧地移除了所有已知不安全的算法和协商机制,只保留经过充分验证的方案。
TLS 1.3 仅有的 5 个密码套件
全部采用 AEAD 认证加密模式,密钥交换由独立扩展处理
TLS_AES_128_GCM_SHA256最常用
TLS_AES_256_GCM_SHA384高安全
TLS_CHACHA20_POLY1305_SHA256移动端首选
TLS_AES_128_CCM_SHA256IoT 友好
TLS_AES_128_CCM_8_SHA2568字节标签
注意:TLS 1.3 的密码套件格式与 TLS 1.2 不同。TLS 1.3 套件仅指定 AEAD 算法和哈希函数,密钥交换算法由 KeyShare 扩展独立协商,认证算法由 SignatureAlgorithms 扩展独立协商。这种解耦设计使协议更加灵活和安全。
密钥计算过程
TLS 1.2 — PRF 密钥派生
# TLS 1.2 密钥派生流程
Pre_Master_Secret:
RSA模式: RSA_Decrypt(ClientKeyExchange)
ECDHE: ECDH(私钥, 对方公钥)
Master_Secret = PRF(
Pre_Master_Secret,
"master secret",
Client_Random + Server_Random # 拼接
) # 输出 48 字节
Key_Block = PRF(
Master_Secret,
"key expansion",
Server_Random + Client_Random # 注意顺序反转!
)
# 从 Key_Block 中按顺序提取:
├── client_write_MAC_key (20字节, SHA-1)
├── server_write_MAC_key (20字节)
├── client_write_key (16字节, AES-128)
├── server_write_key (16字节)
├── client_write_IV (4字节)
└── server_write_IV (4字节)TLS 1.3 — HKDF 密钥派生
# TLS 1.3 密钥派生流程 (HKDF)
Shared_Secret = ECDHE(私钥, 对方公钥)
# ┌─── HKDF-Extract ───────────────────┐
# │ Input : salt=0, IKM=Shared_Secret │
# │ Output: Early Secret │
# └─────────────────────────────────────┘
│
├──→ Binder Key (PSK 场景)
│
▼
# HKDF-Extract("", Derive-Secret(Early, "derived"))
# → Handshake Secret
Handshake_Secret = HKDF-Extract(
salt = HKDF-Expand(Early, "derived", ""),
IKM = Shared_Secret
)
# 派生 Handshake Traffic Keys:
client_handshake_key = HKDF-Expand(
Derive-Secret(Handshake_Secret,
"c hs traffic", Transcript_Hash),
"key", 16)
server_handshake_key = ...
# 握手完成后:
master_secret = HKDF-Extract(
salt = Handshake_Secret,
IKM = 0)
# → 派生 Application Traffic Keys核心要点总结
01
TLS 1.3 将 KeyShare 前置到 ClientHello,握手仅需 1-RTT,速度提升约 50%
02
TLS 1.3 强制使用临时 DH 密钥交换(ECDHE),所有连接都具备前向保密
03
TLS 1.3 在 ServerHello 之后立即加密,证书等敏感信息不再明文传输
04
TLS 1.3 大幅简化密码套件(仅 5 个 AEAD 组合),消除配置错误风险
05
0-RTT 恢复虽快但有重放攻击风险,应仅用于幂等请求
06
生产环境应禁用 TLS 1.0/1.1,优先使用 TLS 1.3,兼容性需求可保留 TLS 1.2