网络安全 · 深度解析

HTTPS TLS 握手过程深度解析

从 TLS 1.2 的两次往返到 TLS 1.3 的一次往返 —— 理解现代 Web 安全基石的演进之路

TLS 1.0 ❌TLS 1.1 ❌TLS 1.2 ✅TLS 1.3 ✅ 推荐

TLS 的三大安全保证

机密性 (Confidentiality)

通过对称加密算法(如 AES-GCM)保护传输数据,第三方无法解密读取。

身份认证 (Authentication)

通过 X.509 数字证书和 CA 信任链验证服务器身份,防止中间人冒充。

完整性 (Integrity)

通过 MAC / AEAD 认证标签确保数据未被篡改,任何修改都会被检测到。

握手流程

1-RTT(一次网络往返)更快
1

ClientHello

客户端服务器
2

ServerHello

服务器客户端
3

🔒 加密边界 — Handshake 密钥已就绪

服务器客户端
4

[加密] EncryptedExtensions

加密
服务器客户端
5

[加密] Certificate

加密
服务器客户端
6

[加密] CertificateVerify

加密
服务器客户端
7

[加密] Finished

加密
服务器客户端
8

[加密] Finished

加密
客户端服务器
加密数据传输开始

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.2
2-RTT
TLS 1.3
1-RTT

TLS 1.3 将 KeyShare 嵌入 ClientHello,减少一次往返。首次连接速度提升约 50%。

会话恢复

TLS 1.2
1-RTT
TLS 1.3
0-RTT ⚡

TLS 1.3 支持 0-RTT 早期数据:恢复会话时可在第一条消息就发送应用数据。

前向保密

TLS 1.2
可选
TLS 1.3
强制 ✅

TLS 1.3 移除静态 RSA 密钥交换,强制使用临时 DH(ECDHE),确保前向保密。

证书隐私

TLS 1.2
明文传输
TLS 1.3
加密传输 🔒

TLS 1.3 中服务器证书在加密通道传输,中间人无法窥探用户访问的网站。

密码套件

TLS 1.2
300+ 个
TLS 1.3
仅 5 个

TLS 1.3 仅保留 AEAD 算法组合,大幅简化配置,减少人为错误。

密钥派生

TLS 1.2
PRF
TLS 1.3
HKDF

TLS 1.3 使用 HKDF(基于 HMAC 的密钥派生函数),更安全、更灵活。

TLS 1.3 移除了什么?

TLS 1.3 大刀阔斧地移除了所有已知不安全的算法和协商机制,只保留经过充分验证的方案。

RSA 静态密钥交换

不提供前向保密

静态 DH 密钥交换

不提供前向保密

RC4 流密码

存在已知弱点

3DES (CBC 模式)

Sweet32 攻击

CBC 模式密码套件

Padding Oracle 攻击

SHA-1 / MD5 签名

碰撞攻击已可行

压缩 (DEFLATE)

CRIME 攻击

协商重协商 (Renegotiation)

复杂且易出错

DSA 证书

不再推荐使用

自定义 DH 群组

仅允许标准命名曲线

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