编程技术记录

世界你好!

前向安全

前向安全(Forward Secrecy,简称 PFS)是 TLS(以及其他加密协议)中一个非常重要的安全属性,简单来说:
“即使攻击者将来拿到了服务器的长期私钥(即证书私钥),也无法解密之前已经完成的所有 TLS 会话”
这就是前向安全的核心意义:过去的通信记录永远是安全的,即使私钥彻底泄露。

前向安全在TLS 1.3中强制开启的,安全性由椭圆曲线离散对数问题(ECDLP)保障

ECDH(椭圆曲线 Diffie-Hellman)最核心的数学原理

一句话就能说清楚:“乘法可以随便做,除法几乎做不出来”

我们用最常用、最直观的曲线 X25519 / Curve25519 来解释(TLS 1.3 里 90% 以上用的就是它)。

1. 公共参数(全世界都一样)

  • 选定一个安全的椭圆曲线:y² = x³ + 486662x² + x(模 2²⁵⁵-19)
  • 选定一个基点(base point)G,一个固定的点,坐标是已知的:
    G = (9, 447…)(具体数字不重要,只要大家用同一个就行)

2. 双方各自生成临时私钥(就是随机数)

  • 爱丽丝(Alice,客户端)随机选一个 256 bit 的整数作为私钥:
    a = 随机数(比如 3f1a…c2,绝对保密!)
  • 鲍勃(Bob,服务器)也随机选一个 256 bit 的整数:
    b = 随机数(比如 7d2b…e9,绝对保密!)

3. 计算并公开“公钥”(其实就是把私钥乘以基点 G)

  • 爱丽丝算出自己的临时公钥:
    A = a × G (把基点 G “加”自己 a 次)
  • 鲍勃算出自己的临时公钥:
    B = b × G

这一步叫标量乘法(scalar multiplication),很快就能算。

4. 双方互换公钥(在网络上明文发送,没关系!)

爱丽丝把 A 发给鲍勃
鲍勃把 B 发给爱丽丝

5. 双方各自再做一次标量乘法,得到共享秘密 Z

  • 爱丽丝算:Z = a × B
  • 鲍勃算: Z = b × A

奇迹发生了:
a × B = a × (b × G) = (a × b) × G
b × A = b × (a × G) = (b × a) × G

因为乘法交换律,a×b = b×a,所以两个 Z 完全相等

这就是共享秘密 Z(32 字节),网络上从来没有传输过 Z,攻击者只看到 A 和 B。

6. 为什么攻击者算不出 Z?(数学陷阱)

攻击者看到:

  • G(公开)
  • A = a × G(公开)
  • B = b × G(公开)

他想求 Z = a × b × G
→ 必须先从 A 求出 a,或者从 B 求出 b
→ 这就是椭圆曲线离散对数问题(ECDLP)

目前人类最好的算法要花大约 2¹²⁸ 次运算才能破解 X25519(相当于 300 亿亿亿年),完全不可能。

这就是“乘法容易,除法几乎做不出来”的本质。

超级简化的数字比喻(虽然现实不是素数乘法,但帮助理解)

把椭圆曲线上的“点加”想象成普通乘法:

  • G = 5(基点)
  • 爱丽丝私钥 a = 7
  • 鲍勃私钥 b = 13

爱丽丝发:A = 5⁷ = 78125
鲍勃发:B = 5¹³ = 1220703125

爱丽丝算:78125¹³ = 4038967834731580443708050254247865495926816947758197784423828125
鲍勃算:1220703125⁷ = 4038967834731580443708050254247865495926816947758197784423828125

攻击者看到 78125 和 1220703125,想求出 7 或 13 ,也不容易。
椭圆曲线只是把“指数”换成了“点重复相加”,但数学难度被做得更高。

总结:ECDH 全过程一句话

  1. 大家约定一个起点 G
  2. 各自用自己的私钥(随机数)把 G “乘”很多次得到公钥,公开交换
  3. 再把对方的公钥乘上自己的私钥,得到同一个共享秘密 Z
  4. 因为离散对数难题,谁也反推不出对方的私钥 → Z 永远安全

这就是 TLS 1.3 里每一次握手都能实现完美前向安全的数学根基。

发表回复