4.3 Diffie-Hellman 密钥交换:公开信道协商秘密


4.3 Diffie-Hellman 密钥交换:公开信道协商秘密

本节摘要:Diffie-Hellman 让从未谋面的双方在全被窃听的信道上算出同一把对称密钥:安全性悬在离散对数难题上,窃听者看得见每一个公开数字,却推不出最终秘密。本节手算一遍小参数全过程,讲清中间人攻击为什么是它的天然软肋,以及 TLS 1.3 为什么只保留临时密钥版本以换取前向安全。

在众目睽睽下算出同一个秘密

想象一间四面漏风的电报房:你与对方之间的每一条消息都会被完整抄送敌方。传统思维下,在这种信道上建立共享密钥是无解的——密钥一经传递即告泄露。Diffie 与 Hellman 1976 年的方案绕开了"传递":双方各自就地生成一个私密随机数,只交换派生值,再各自把对方的派生值与自己的私数做一次模幂运算——殊途同归,得到同一个数。全程公开可查,秘密却始终没有出现在任何一条线上。

协议只有三步,公开放在明面上的参数是两个:一个大素数 p 与它的生成元 g。手算一个小例子(真实参数是 2048 位级别,此处 p=23、g=5):

  • Alice 选私密指数 a=6,计算 A = 5⁶ mod 23 = 8,把 8 发给 Bob;
  • Bob 选私密指数 b=15,计算 B = 5¹⁵ mod 23 = 19,把 19 发给 Alice;
  • Alice 算共享密钥 s = 19⁶ mod 23 = 2;Bob 算 s = 8¹⁵ mod 23 = 2。

双方得到的都是 2。窃听者掌握全部公开量:p、g、8、19。要推出 s,最直接的路是先求出 a 或 b——也就是解离散对数 5^a ≡ 8 (mod 23)。小参数下手算都行,但当 p 是 2048 位的大素数时,这件事在经典计算机上被公认为不可行:**共享密钥的安全性 = 离散对数问题的难度。**妙处还在于指数运算的可交换性:(g^b)^a 与 (g^a)^b 都是 g^(ab)——数学保证了殊途同归。

图:Diffie-Hellman 密钥交换时序(含中间人攻击对照)

图:Diffie-Hellman 密钥交换时序(含中间人攻击对照)

二、软肋与补丁:认证与临时性

裸协议的软肋不在数学,在"不知道对方是谁"。中间人攻击者坐在 Alice 与 Bob 之间,与 Alice 独立完成一次 DH、再与 Bob 完成一次,两把会话密钥分别到手;他转发并篡改流量,双方用"成功协商"的密钥加密通信,却不知对面隔着一个翻译。DH 的正确用法永远是先认证再交换:用数字签名(RSA 或后两节的技术)把"这份 g^a 确实出自 Alice"钉死,认证体系即第六章的证书与 PKI。

第二个补丁关乎"密钥的寿命"。若双方常年用同一对 DH 静态密钥,那么一旦这对私钥泄露,历史上所有用它协商过的会话全部可解。临时 DH(DHE/ECDHE)的做法是每次会话现场生成全新的指数对、用完即弃:私钥从未落盘、泄无可泄,即使攻击者日后拿到服务器长期私钥,也只能解开"以后"的握手,无法回溯已销毁的历史会话——这就是前向安全(forward secrecy)。TLS 1.3 之所以彻底删除静态 RSA 密钥交换、强制临时密钥协商,正是为把前向安全变成默认属性。

参数上还有一条时间线值得记:早期实现常用 1024 位素数,已被认定只有约 80 位强度,学界对预计算式的攻击(针对特定素数的 Logjam)也证明"常用素数"本身可能被定向攻坚;现行规范(RFC 7919 一族)要求有限域 DH 使用 2048 位及以上的标准安全素数。要继续缩短长度、提升速度,就得把舞台从乘法群搬到椭圆曲线——那是 4.4 节的剧场。

用 Python 复演上面的小例子并指出窃听者的死路:

p, g = 23, 5 # 真实场景:p 为 2048 位以上的安全素数 a, b = 6, 15 # 双方各自的私密指数(绝不上信道) A, B = pow(g, a, p), pow(g, b, p) # 公开交换的派生值 print(A, B) # -> 8 19 s_alice = pow(B, a, p) # Alice 用自己的 a 与对方的 B s_bob = pow(A, b, p) # Bob 用自己的 b 与对方的 A print(s_alice, s_bob) # -> 2 2,共享密钥达成 # 窃听者的暴力路线:穷举 x 使 pow(g, x, p) == A crack = next(x for x in range(p) if pow(g, x, p) == A) print(crack) # 小参数能穷举出 6;p 为 2048 位时穷举不可行

💡 关键直觉:Diffie-Hellman 的秘密从未"存在"于任何一条消息里——它只存在于双方的脑子里,在纸上与线上出现的所有数字都只是它的影子。窃听者面对的不是密文,是四五个无辜的公开数字。

参数与实现的实务问答

问:素数 p 与生成元 g 该怎么选?不要自己编造。工程实践采用标准文档公布的"安全素数"(形如 2q 加一、q 也是素数,压平小子群攻击面)与配套生成元,并注意攻击者可能对"所有人共用同一素数"做多年期的预计算投资——定期跟进参数建议同样属于密钥管理。

问:DHE 与 ECDHE 有什么区别?数学同构,舞台不同:前者在大素数乘法群里跑,密钥长、速度慢;后者在椭圆曲线点群里跑,三十余字节的公钥即可达到同等强度——4.4 节的等效账在这里直接兑现为协议选择。

问:密钥交换完成后,临时私数怎么处理?立即清零。前向安全的全部承诺都建立在"这对指数从未落盘、用完即焚"之上——任何日志、转储或调试输出把它记下来,前向安全就变成了前向脆弱。

问:量子计算机对 DH 意味着什么?与 RSA 同一判决:离散对数在 Shor 算法下多项式时间可解,这正是 7.3 节迁移清单上的头号对象。

三个历史注脚

注脚一,英国通信总部的威廉姆森在 1974 年独立得出与 DH 等价的方案,作为机密封存至解密——公钥革命的"双生史"里,密钥协商同样有两位发现者。注脚二,Diffie-Hellman 的原始专利 1997 年期满,恰好赶在电子商务起飞前夜,客观上为 TLS 的普及清除了法律路障——一项专利的到期影响了整个互联网的加密进程。注脚三,论文发表当年,两位作者深知工程界不会立刻相信"公开协商安全",他们的演示刻意选在学术会议上现场进行:窃听者与观众看到的材料完全相同,秘密却在台上台下两人之间成立。数学的表演性,在此刻胜过千言万语。

本节要点回顾

  • 三步协议:公开 p 与 g,双方各持私密指数交换模幂派生值,各自算出同一个共享数;
  • 安全根基:离散对数难题;有限域版本要求 2048 位及以上安全素数,小素数与常用素数均已被定向攻破过;
  • 中间人攻击:无认证的 DH 可被会话劫持拆解成两次独立交换,必须与签名或证书配合;
  • 前向安全:临时指数用完即弃,长期私钥泄露也解不开历史会话,TLS 1.3 以此为默认。

同一枚离散对数硬币,还有更小、更快的铸法。下一节把乘法群换成椭圆曲线上的点群,看 256 位密钥如何干 3072 位 RSA 的活。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U