02

前向安全 vs 后向安全 · 直觉图

Intuition · 攻击者视角

即使密钥被盗,前面消息仍安全 · DH 翻转后,未来消息也安全

🎯 思想实验: 假设攻击者在某一时刻拿到完整状态 (CK_n, MK_n),前/后消息分别会怎样? ✓ ZONE A · 前向安全保护 M1, M2, M3 (历史消息) ✗ ZONE B · 攻击窗口 M4, M5 (同链可推) ✓ ZONE C · 后向安全保护 M6, M7, M8 (DH 翻转后) time ChainKey: CK₁ KDF CK₂ CK₃ CK₄ CK₅ CK₆ 链断 CK'₁ CK'₂ CK'₃ CK'₄ t=1 t=2 t=3 ⚡ BREACH @ t=3.5 攻击者拿到 CK₄ t=4 t=5 🔄 DH RESET @ t=5.5 收到对方新公钥 t=6 t=7 t=8 t=9 MessageKey: MK₁ 🔒 MK₂ 🔒 MK₃ 🔒 MK₄ 🔓 MK₅ 🔓 MK'₁ 🔒 MK'₂ 🔒 MK'₃ 🔒 MK'₄ 🔒 🛡️ 前向安全 · 为什么 M₁, M₂, M₃ 仍然安全? 机制 — KDF 单向性 CK₃ → KDF → CK₄ → KDF → CK₅ 攻击者有 CK₄, 但 KDF (HMAC-SHA256) 单向 ❌ 无法反推 CK₃, ❌ 无法反推 CK₂, … 机制 — MessageKey 用完即丢 MK₁/MK₂/MK₃ 加密完后立即从内存删除 ❌ 攻击者即使翻内存也找不到 🛡️ 后向安全 · 为什么 M'₁ ~ M'₄ 仍然安全? 机制 — DH Ratchet 注入新熵 收到对方新 ratchet_key → DH(我_priv, 对方_pub_new) → 全新 RootKey → 全新 ChainKey CK'₁ ✅ 新链与旧 CK₅ 在数学上独立 前提 — 攻击者未拿到长期密钥 攻击者只有 CK₅ (一时状态), 没有 IK 长期私钥 → 无法预测 / 中间人 DH 翻转后的新公钥 🔗 类比: 想象一根棘轮链 — 每转一格派生一把钥匙、用完即丢 (前向); DH 翻转 = 整根链被换掉 (后向) 💡 带走结论: 前向安全靠 KDF 单向性 · 后向安全靠 DH Ratchet 注入新随机性
前向

Forward Secrecy · 保护历史消息

  • • 又叫"完美前向安全 (PFS)"
  • • KDF 用 HMAC-SHA256,单向不可逆
  • • 用完即丢策略:MK_n 加密后立即从内存清除
  • • 即使整个客户端被攻破,历史消息也不可恢复
后向

Post-Compromise Security · 自我修复

  • • 又叫"未来安全"或"自愈性"
  • • 触发条件:双方至少一次 ping-pong 通信
  • • DH 注入对方的新公钥随机性 → 新 RootKey
  • • 攻击者必须持续监控才能破坏(拿一次状态不够)
攻击

攻击窗口 · 哪些消息会丢?

  • • 只有"被拿走状态那一刻"到"下次 DH 翻转"之间的消息会丢
  • • 在 Signal 实践中:通常是 1~2 个对话回合
  • • 鼓励用户频繁互发消息以加速 DH 翻转
  • • 长期沉默的会话风险窗口最长
💡 一句话理解: Signal 把"安全性"切成两段独立保险:前向安全(KDF 单向)保护过去,后向安全(DH 注入)保护未来。 攻击者短时拿到状态,只能解开"中间一小段"的消息——这就是为什么端到端加密不靠"密钥永远不丢",而靠"密钥永远在变"。

📚 基础知识速查 · Reference

不熟悉以下底层概念? 这里是 30 秒回顾。

数学KDF 单向性

HMAC-SHA256 是密码学哈希, 从 output 反推 input 的复杂度 ≈ 2¹²⁸, 在物理可计算资源下不可行。

output = HMAC(key, data) — 单向

数学DH 离散对数难题

Curve25519 上的 ECDLP: 给定 g 和 g·a, 求 a 是计算困难问题。这就是为什么传公钥安全。

给 P = a·G, 求 a → 困难

概念后向安全 (PCS)

又叫"自愈性 (Self-Healing)"。会话状态被泄漏后, 通过引入新随机性可在数轮通信后恢复安全。

Post-Compromise Security

概念临时密钥 (Ephemeral Key)

单次会话使用、用完即丢的密钥。是前向安全的工程实现手段 — 攻击者翻内存也找不到。

generate → use → zeroize