密语 · CIPHER | 目录 CH.15 / 26
绝密
Phase 4 · 公钥革命

Diffie-Hellman 密钥交换

1976 年,两个人证明了:素不相识的双方,可以在满是窃听者的房间里当众商定一个只有他们知道的秘密。

阅读 ~15 分钟 前置 第 14 章 Demo 交互式 DH 协商 + Eve/Mallory

这是密码学的分水岭。在 Diffie 和 Hellman 之前,"共享密钥"这件事被认为必须事先线下完成。他们证明了这个"常识"是错的——而且解法优雅得近乎魔术。你每一次 HTTPS 握手,背后都在跑它的现代变体。

一、颜色混合的直觉

先忘掉数学,想象混合颜料。有一个关键的不对称:混合两种颜色很容易,但从混合色分离出原色几乎不可能(这就是第 14 章的单向函数)。Alice 和 Bob 隔空协商,当着窃听者 Eve 的面:

  1. 两人公开约定一个公共色(比如黄色)。Eve 看得一清二楚。
  2. Alice 私下选一个秘密色(红),混进公共色 → 得到橙色,公开寄给 Bob
  3. Bob 私下选一个秘密色(蓝),混进公共色 → 得到绿色,公开寄给 Alice
  4. Alice 把收到的绿色,再混进自己的红 → 得到某个棕色
  5. Bob 把收到的橙色,再混进自己的蓝 → 得到同一个棕色!

两人都得到了 "黄+红+蓝" 的混合色,而这个最终色他们从未直接传输过。Eve 看到了黄、橙、绿,但要配出那个棕色,她必须从橙色里"减掉"红或从绿色里"减掉"蓝——而分离颜色是做不到的。公共信道上跑的全是公开信息,共享秘密却凭空诞生了。

二、把颜料换成数字

"混合颜色"的数学化身,就是第 14 章的模幂。公共色是 (g, p),秘密色是各自的私钥指数,"混合"就是求幂:

步骤AliceBobEve 看到
公共参数约定素数 p 和底数 gg, p
选私钥秘密 a秘密 b—(看不到)
算公钥A = gᵃ mod pB = gᵇ mod pA, B
交换← 收到 B收到 A →A, B 在信道上
算共享密钥s = Bᵃ mod ps = Aᵇ mod p???

为什么两人算出同一个 s?因为指数可以交换顺序:

Alice: (gᵇ)ᵃ = gab  =  Bob: (gᵃ)ᵇ = gab  (mod p)

Eve 手里有 g, p, A=gᵃ, B=gᵇ,想算出 s=g^{ab},就必须先从 A 反推出 a(或从 B 反推 b)——这正是离散对数难题。p 一大,她就卡死了。这个"Eve 拿到两个公钥也算不出共享秘密"的假设,叫 计算性 Diffie-Hellman 假设(CDH)

三、亲手跑一遍(并试着当 Eve)

下面的 Demo 让你完整走一遍 DH。点"协商",看 Alice 和 Bob 各自算出相同的共享密钥。然后切到 Eve 视角:你只拿到公开信息,试试能不能在合理时间里算出共享密钥——参数小的时候你能暴力破(离散对数在小 p 下可解),但把 p 调大,你会亲身体会到那堵墙。

DEMO Diffie-Hellman 协商
Alice 和 Bob 永远得到相同的 s,却从未在信道上发送过它。Eve 只能靠暴力试离散对数——把 p 改成一个更大的素数(如 7919),再点破解,感受一下墙有多硬。

四、致命前提:你确定对面是 Bob 吗?

DH 完美抵御被动窃听者 Eve。但还记得第 1 章那个更坏的角色 Mallory(主动攻击者)吗?DH 对她毫无防备

问题在于:DH 让双方协商出一把共享密钥,却没有验证对方的身份。Mallory 可以站在中间,对 Alice 假扮 Bob、对 Bob 假扮 Alice,和两边各做一次 DH:

Alice ⟷ Mallory ⟷ Bob
Alice 以为在和 Bob 协商,其实密钥是和 Mallory 的;
Bob 以为在和 Alice 协商,其实密钥也是和 Mallory 的。

于是 Mallory 拿到两把密钥,坐在中间:Alice 发来的消息她能解密、看完、再用另一把密钥重新加密转发给 Bob。双方全程以为通信是安全的,实际每个字都经过 Mallory 的手。这就是中间人攻击(MITM)

DEMO 中间人攻击
注意:Alice 和 Bob 各自都"成功协商"了密钥,没有任何报错——但两把密钥都在 Mallory 手里。裸 DH 无法察觉这件事。
DH 需要"身份"来兜底

裸 DH 只解决了"协商密钥",没解决"确认对方是谁"。要堵住 MITM,必须给 DH 的公钥加上认证——用数字签名证明"这个公钥确实来自 Bob"(第 18 章),而签名的可信又来自证书/CA 体系(第 18、19 章)。TLS 握手(第 19 章)本质就是"DH 协商密钥 + 证书签名认证身份"的组合。记住这条接缝:密钥交换和身份认证是两件必须同时做对的事——这正是第 1 章说的"错在接缝"。

现代 DH 长什么样

前向保密(Forward Secrecy):实践中用临时(ephemeral)DH——每次会话都生成一次性的 a、b,用完即弃。好处是即使某天你的长期私钥泄露,攻击者也无法解密之前录下的历史流量,因为那些会话密钥早已不存在。这是 TLS 1.3 的强制特性,也是第 25 章 Signal 协议的核心思想。
椭圆曲线 DH(ECDH):把"素数钟面"换成"椭圆曲线"(第 17 章),用短得多的密钥达到同等安全。今天的 TLS/Signal 用的几乎都是 X25519 这个 ECDH 变体。原理完全一样,只是换了更高效的数学舞台。

DH 让双方协商出密钥,但我们还缺两样东西:一是能加密给特定公钥、二是能签名证明身份。这两件事,历史上第一个把它们一次性全做到的算法,就是大名鼎鼎的 RSA。下一章,我们亲手用小素数把它从密钥生成到签名完整跑一遍。

本章要点

  • DH 让双方在公开信道上协商出共享密钥:各自 gˣ mod p 交换公钥,再互相求幂得 g^{ab}
  • 安全性靠离散对数难题:Eve 拿到两个公钥也无法反推私钥或共享密钥。
  • 裸 DH 不认证身份,易受中间人攻击;必须叠加签名/证书来确认对方是谁。
  • 现代实践:临时 DH 提供前向保密,ECDH(X25519)用更短密钥达同等安全。