跳转到内容

Logjam 2015 — 全世界共用一把锁,国家级窃听者一次撬完

待复核

Logjam 是 2015 年 David Adrian 等人发的一篇攻击论文,把当时全球 HTTPS / VPN / SSH 用的 Diffie-Hellman 密钥协商扒了个底朝天。结论一句话:绝大多数服务器不是用自己生成的素数,而是用同一把”公共大锁”,只要花一年算力把这把锁的内部结构提前算好,之后任何用这把锁的会话都能在几分钟里被解密

日常类比:一栋大楼住一千户,物业为了省事,给每家发的门锁全是同一款、同一齿型。窃贼花几个月做一把万能钥匙,之后哪一户都能进。Logjam 干的就是这件事,只不过”门锁”是 1024 位素数,“窃贼”是国家级机构,“几个月”是约一年的专用硬件预算。

这篇论文给两件事直接定调:(1)解释了 Snowden 文件里 NSA “能解密大量 VPN” 到底怎么做到;(2)推动 TLS 1.3 砍掉弱 finite-field DHE,默认走向 ECDHE(强群只留 RFC 7919 那几组)。在密码工程史上很少有论文一篇就能改一整代标准的方向,Logjam 是其中最干脆的一例。

不理解 Logjam,下面这些事都讲不清:

  • 为什么 TLS 1.3 不只是”少一轮握手”,而是把好几个 1990 年代沿用至今的密码原语整体砍掉
  • 为什么 RFC 7919 之后,浏览器突然要求 DH 参数 ≥ 2048 位、还得是几个写死的标准群
  • 为什么 diffie-hellman-1976 的数学没问题、协议也没问题,工程落地却能整体崩盘——参数复用就是单点故障
  • 为什么 heartbleed-2014 是实现 bug,Logjam 是”标准 + 默认值 + 性能折衷”三方共谋的系统性 bug,后者更难修
  • 为什么后量子密码(PQC)从 NIST 选 Kyber 这一刻起就在重演 Logjam 的故事——参数选错一次代价巨大,所以慢工出细活

Logjam 把三件独立的事拼成一击致命:

  1. 数学事实:解 1024 位素数下的离散对数,最贵的那一步(数域筛 NFS 的多项式选择 + sieving + 线性代数)只依赖素数 p 本身,不依赖具体目标。换句话说,算一次能解所有用同一把 p 的会话。这种”参数预计算”在椭圆曲线密码(ECDLP)里根本不存在,是 finite-field 独有的结构性弱点。

  2. 工程事实:扫描全网发现,单一个 1024 位素数被 Alexa Top 100 万 HTTPS 网站里支持 DHE 的 37% 共用;两个素数覆盖了大多数 IPsec VPN 和 SSH 服务器。原因是 Apache / OpenSSL 默认参数 + RFC 5114 写死了几个”标准群”,运维同学几乎不会去改这个看起来”已经经过审查”的默认值。

  3. 协议事实:TLS 仍保留 1990 年代为美国出口管制留的 512 位 “export-grade” 密码套件。中间人能在握手时把客户端要求的强参数偷换成 export 弱参数——这一步叫 降级攻击,是 Logjam 主动攻击模式的钥匙。

把三者叠起来:攻击者花一次性大钱预算 1024 位的内部结构,之后用降级攻击把会话拽到 512 位(论文里实测一周破完),或者直接在 1024 位群里查表。

结果就是大规模被动解密——攻击者不用主动做任何事,只要早就把流量录下来,等预计算完成再回放即可解开。主动降级与被动查表,其实是同一份预计算资产的两种用法。

案例 1:降级攻击在握手里发生了什么

Section titled “案例 1:降级攻击在握手里发生了什么”

正常 TLS 握手,客户端发 ClientHello 列出支持的密码套件,服务器选一个回。Logjam 的中间人改写 ClientHello,只留 export-grade DHE,再把服务器的回包改回去骗客户端。客户端以为自己谈成了强参数,实际整个会话用的是 512 位 DH。

代码层抽象(伪 OpenSSL 调用):

# 客户端原本想要的
client_hello.cipher_suites = ['DHE-RSA-AES256-SHA', 'DHE-RSA-EXPORT']
# 中间人改写为
client_hello.cipher_suites = ['DHE-RSA-EXPORT']
# 服务器配合给出 512-bit 参数 → 客户端没有警告 → 解密

逐部分解释:

  • 第一行:客户端同时报强套件和遗留 export 套件,本意是「能强则强」。
  • 第二行:中间人把列表裁成只剩 export,服务器就按弱参数回应。
  • 第三行:客户端若未校验参数位数,会把弱会话当成正常会话继续。

为什么 Finished 消息识不破?TLS 1.2 之前的 Finished 摘要没把 server-supplied DH 参数完整哈希进去——协议设计漏洞,直到 Logjam 才被推到台前修复。修复办法:拒绝弱于本地阈值的 DH 参数(FF-DHE 最小 2048)、彻底关掉 export 套件;浏览器从 2015 年 6 月开始硬性改阈值。

论文里用学术资源(CADO-NFS + 几千 CPU 核)演示:单个 512 位素数预计算约一周;之后每个会话的离散对数约 90 秒。在握手超时时间内能算完——这是降级攻击能实时生效的关键。注意 90 秒里大部分是单次 descent 步骤,多项式选择 / sieving / 线性代数已在前一周一次性算完,每次会话不重复。

工程含义:握手超时普遍在 30–120 秒;攻击者只要把这一次离散对数压在窗口内,浏览器就感知不到中间人,连 warning 都不会弹。

案例 3:为什么 1024 位也不安全(含扫描数据)

Section titled “案例 3:为什么 1024 位也不安全(含扫描数据)”

作者估算单个 1024 位素数预计算成本:约几亿美元专用硬件 + 一年时间,等于国家年度情报预算的零头。扫描 Alexa Top 100 万 HTTPS / 全网 SMTP / IPsec / SSH 后更刺眼:

  • 约 8.4% HTTPS 站仍接受 export-grade DHE
  • 单个 1024 位素数被约 37% 的 DHE 站点共用
  • IPsec 默认 Group、SSH group1-sha1 也高度集中

性价比惊人——一次投入永久可用,正好对上 Snowden 备忘录里「能解密大量 VPN」的描述。工程上「全网就这两三个素数」才让威胁模型立体;被动监听 + 长期存储 + 未来解密是国家级常态,这也是后量子密码(PQC)被提前推动的同一逻辑。

  1. “用大家都用的参数更安全”是错的。直觉以为标准群经过审查,但 Logjam 证明恰恰相反:标准群是单点目标,攻击成本被所有受害者均摊给攻击者。唯一安全的复用方式是椭圆曲线——曲线的离散对数没有 NFS 这种预计算结构。这条教训直接写进了 tls-1.3 的设计原则。

  2. 降级攻击的根因不是算法弱,是”协议保留旧选项”。TLS 为兼容性留 export 套件十几年,没人想到还能被利用。教训:废弃的密码套件必须真的从代码里删掉,不能只是”默认关闭”。客户端代码里只要还能解析弱参数,中间人就有空间塞东西进来。

  3. “forward secrecy” 名字是误导。DHE 号称提供前向安全,但如果素数本身被攻破,所有过去会话一起暴露——这就是论文标题 “Imperfect Forward Secrecy” 的意思。真正的前向安全要求每会话独立的密钥协商,但素数共享让”独立”成了假象。

  4. 修补很慢,出口管制债也难清。Logjam 2015 年 5 月披露,到 2018 年浏览器才彻底拉到 2048 位下限;中间几年大量服务器仍可被攻击。export 套件源于 1990 年代美国出口管制,法律早废了,代码却留了约 20 年——类似 heartbleed-2014 的 heartbeat 扩展,每条历史选项都是潜在攻击面。嵌入式设备 / VPN 网关 / 老旧内网往往没人维护,只能靠浏览器一侧拉下限把它们赶进废弃名单。

Logjam 攻击适用

  • TLS 1.0 / 1.1 / 1.2 + DHE 密码套件 + 默认 1024 位素数
  • IPsec / IKE 默认 Group 2(1024 位)
  • SSH 默认 group1-sha1(1024 位)
  • 任何用 RFC 5114 / Apache 默认参数的服务

Logjam 攻击不适用

  • ECDHE(椭圆曲线 DH)—— 没有 NFS 那种参数特异结构
  • TLS 1.3 —— 强制 ECDHE,弱 FF-DHE 已砍;仅保留 RFC 7919 的强有限域群
  • 一次性自生成 2048 位以上素数的服务(少数)
  • 后量子 KEM(如 Kyber)—— 数学结构不同
  • 2013 年 6 月:Snowden 文件里出现 NSA 备忘录,称能「实时解密大量 VPN 会话」,但没说原理。学界两年没人能复现,圈内一度怀疑是吹牛。
  • 2014 年:Adrian / Heninger / Halderman 等人开始扫全网 DH 参数,发现复用率高得离谱——这是把「吹牛」变成「可解释攻击」的关键观察。
  • 2015 年 5 月:weakdh.org 发布,CCS 2015 收录论文并获最佳论文。同月披露给主流浏览器厂商。
  • 2015 年 6 月:Chrome / Firefox / IE / Safari 紧急把 DH 下限拉到 1024,年底拉到 2048。期间出现一批因下限上调导致老旧服务连不上的工单。
  • 2018 年 8 月tls-1.3 RFC 8446 发布,标准层面砍掉弱 finite-field DH 选项,默认 ECDHE,强群走 RFC 7919。

从 Snowden 提示到学界复现到协议彻底修复,整整 5 年。这条时间线本身就是「理论威胁」→「学术 PoC」→「工业修复」的标准节奏。

  1. 数学正确 ≠ 系统安全。Diffie-Hellman 协议本身没问题,落地参数选择才是命门。安全分析必须看完整栈:算法 / 参数 / 默认值 / 兼容选项缺一不可。
  2. 共享标准是双刃剑。复用经过审查的参数比每家自己生成更安全——除非攻击者也复用预计算成果。判断”复用是否安全”的核心是底层数学问题有没有”参数特异预计算”通道。
  3. 降级攻击是协议设计的长尾债。每留一个废弃选项,未来都可能被中间人当工具用。删旧选项比加新功能重要,但工程上几乎总被低优先级。
  4. 椭圆曲线赢在数学结构。NFS 在曲线上失效不是巧合,是椭圆曲线离散对数问题(ECDLP)没有”子指数”算法——这是 tls-1.3 强制 ECDHE 的根本理由。
  5. “今天的密文是明天的明文”。国家级对手会先存后解,密码体系的安全裕度必须按 10-30 年算,不是按今天的算力。这条逻辑现在又驱动着 PQC 标准化。
  • diffie-hellman-1976 —— Logjam 攻击的就是 1976 年这套协议的工程实现
  • tls-1.3 —— 砍掉弱 FF-DHE、默认 ECDHE 的最终成品,Logjam 是直接动因
  • heartbleed-2014 —— 2014 年的实现 bug,与 Logjam 形成 “实现 vs 标准” 对照
  • lucky13-2013 —— 同期 TLS 攻击,针对的是 MAC-then-encrypt 模式
  • aes —— 对称加密在 Logjam 里没问题,问题全在密钥协商一侧
  • diffie-hellman —— 概念入门页,理解协议本身后再读 Logjam 的攻击思路