Logjam 2015 — 全世界共用一把锁,国家级窃听者一次撬完
是什么
Logjam 是 2015 年 David Adrian 等人发的一篇攻击论文,把当时全球 HTTPS / VPN / SSH 用的 Diffie-Hellman 密钥协商扒了个底朝天。结论一句话:绝大多数服务器不是用自己生成的素数,而是用同一把”公共大锁”,只要花一年算力把这把锁的内部结构提前算好,之后任何用这把锁的会话都能在几分钟里被解密。
日常类比:一栋大楼住一千户,物业为了省事,给每家发的门锁全是同一款、同一齿型。窃贼花几个月做一把万能钥匙,之后哪一户都能进。Logjam 干的就是这件事,只不过”门锁”是 1024 位素数,“窃贼”是国家级机构,“几个月”是约一年的专用硬件预算。
这篇论文给两件事直接定调:(1)解释了 Snowden 文件里 NSA “能解密大量 VPN” 到底怎么做到;(2)逼着 TLS 1.3 把整个 finite-field DH 体系扔掉,只留椭圆曲线。在密码工程史上很少有论文一篇就能改一整代标准的方向,Logjam 是其中最干脆的一例。
为什么重要
不理解 Logjam,下面这些事都讲不清:
- 为什么 TLS 1.3 不只是”少一轮握手”,而是把好几个 1990 年代沿用至今的密码原语整体砍掉
- 为什么 RFC 7919 之后,浏览器突然要求 DH 参数 ≥ 2048 位、还得是几个写死的标准群
- 为什么 diffie-hellman-1976 的数学没问题、协议也没问题,工程落地却能整体崩盘——参数复用就是单点故障
- 为什么 heartbleed-2014 是实现 bug,Logjam 是”标准 + 默认值 + 性能折衷”三方共谋的系统性 bug,后者更难修
- 为什么后量子密码(PQC)从 NIST 选 Kyber 这一刻起就在重演 Logjam 的故事——参数选错一次代价巨大,所以慢工出细活
核心要点
Logjam 把三件独立的事拼成一击致命:
-
数学事实:解 1024 位素数下的离散对数,最贵的那一步(数域筛 NFS 的多项式选择 + sieving + 线性代数)只依赖素数 p 本身,不依赖具体目标。换句话说,算一次能解所有用同一把 p 的会话。这种”参数预计算”在椭圆曲线密码(ECDLP)里根本不存在,是 finite-field 独有的结构性弱点。
-
工程事实:扫描全网发现,单一个 1024 位素数被 Alexa Top 100 万 HTTPS 网站里支持 DHE 的 37% 共用;两个素数覆盖了大多数 IPsec VPN 和 SSH 服务器。原因是 Apache / OpenSSL 默认参数 + RFC 5114 写死了几个”标准群”,运维同学几乎不会去改这个看起来”已经经过审查”的默认值。
-
协议事实:TLS 仍保留 1990 年代为美国出口管制留的 512 位 “export-grade” 密码套件。中间人能在握手时把客户端要求的强参数偷换成 export 弱参数——这一步叫 降级攻击,是 Logjam 主动攻击模式的钥匙。
把三者叠起来:攻击者花一次性大钱预算 1024 位的内部结构,之后用降级攻击把会话拽到 512 位(论文里实测一周破完),或者直接在 1024 位群里查表。结果就是大规模被动解密——攻击者不用主动做任何事,只要早就把流量录下来,等预计算完成再回放即可解开。
实践案例
案例 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 参数 → 客户端没有警告 → 解密为什么客户端不能在最后通过 Finished 消息识破?因为 TLS 1.2 之前的 Finished 摘要里没把 server-supplied DH 参数完整哈希进去——这是一个被忽视的协议设计漏洞,直到 Logjam 才被推到台前修复。
修复办法两条:客户端拒绝接收弱于本地阈值的 DH 参数(FF-DHE 最小 2048)、彻底关掉 export 套件。浏览器是从 2015 年 6 月开始硬性改阈值的。
案例 2:512 位破多快
论文里用学术资源(CADO-NFS + 几千 CPU 核)演示:单个 512 位素数预计算约一周;之后每个会话的离散对数 ~90 秒。在握手超时时间内能算完——这是降级攻击能实时生效的关键。注意 90 秒里大部分是单次”descent”步骤,剩下的多项式选择 / sieving / 线性代数 已经在前一周里一次性算完,每次会话不重复。
工程含义:握手超时时间普遍在 30-120 秒之间,攻击者只要把这一次离散对数压在窗口内,浏览器就完全感知不到中间人插队,连一个 warning 都不会弹。
案例 3:为什么 1024 位也不安全
作者估算单个 1024 位素数预计算成本:约几亿美元的专用硬件 + 一年时间,等于一个国家年度情报预算的零头。考虑到全网就那两三个常用素数,性价比惊人——一次投入永久可用。这正好对上 Snowden 文件里 NSA 内部备忘录”我们能解密大量 VPN 流量”的描述。
学界从此也学到一条经验:被动监听 + 长期存储 + 未来某天解密 是国家级威胁模型的常态。哪怕今天破不开,过几年算力翻倍 / 算法改进就能批量翻译。这也是后量子密码(PQC)现在被提前推动的同一逻辑。
踩过的坑
-
“用大家都用的参数更安全”是错的。直觉以为标准群经过审查,但 Logjam 证明恰恰相反:标准群是单点目标,攻击成本被所有受害者均摊给攻击者。唯一安全的复用方式是椭圆曲线——曲线的离散对数没有 NFS 这种预计算结构。这条教训直接写进了 [[tls-1.3]] 的设计原则。
-
降级攻击的根因不是算法弱,是”协议保留旧选项”。TLS 为兼容性留 export 套件十几年,没人想到还能被利用。教训:废弃的密码套件必须真的从代码里删掉,不能只是”默认关闭”。客户端代码里只要还能解析弱参数,中间人就有空间塞东西进来。
-
“forward secrecy” 名字是误导。DHE 号称提供前向安全,但如果素数本身被攻破,所有过去会话一起暴露——这就是论文标题 “Imperfect Forward Secrecy” 的意思。真正的前向安全要求每会话独立的密钥协商,但素数共享让”独立”成了假象。
-
修补很慢。Logjam 2015 年 5 月披露,到 2018 年浏览器才彻底拉到 2048 位下限。中间几年大量服务器一直可被攻击——证明协议升级在工程上比想象慢一个数量级。原因之一是嵌入式设备 / VPN 网关 / 老旧企业内网根本没维护,靠浏览器 / OS 一侧拉下限把它们逐个赶进废弃名单。
-
“出口管制后遗症”是密码标准独有的债。export 套件源于 1990 年代美国法律对加密强度的限制,法律早废了,代码却留了 20 年。类似 heartbleed-2014 里的 heartbeat 扩展也是历史选项。每条历史选项都是潜在攻击面。
案例 4:扫描数据揭示的真相
Adrian 等人扫了 Alexa Top 100 万 HTTPS / 全网 SMTP / IPsec / SSH,得到几张惊心数据:
- 8.4% 的 HTTPS 站还在接受 export-grade DHE
- 单个 1024 位素数被 ~37% 的 DHE 站点共用
- IPsec VPN 的 group 5 / group 14 是几乎所有商业 VPN 设备的默认值
- SSH 的 group1-sha1 出现在 ~25% 的服务器
数据是论文的杀手锏:理论上”如果攻击者算出共享素数就能怎样怎样”是一回事,工程上”全网就这两三个素数”才让威胁模型瞬间立体。这也是后续大规模扫描类安全研究(heartbleed-2014 / Mirai 扫描 / Shadowserver 报告)的方法论原型。
适用 vs 不适用场景
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,不再支持 finite-field 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” → “工业修复” 的标准节奏。
学到什么
- 数学正确 ≠ 系统安全。Diffie-Hellman 协议本身没问题,落地参数选择才是命门。安全分析必须看完整栈:算法 / 参数 / 默认值 / 兼容选项缺一不可。
- 共享标准是双刃剑。复用经过审查的参数比每家自己生成更安全——除非攻击者也复用预计算成果。判断”复用是否安全”的核心是底层数学问题有没有”参数特异预计算”通道。
- 降级攻击是协议设计的长尾债。每留一个废弃选项,未来都可能被中间人当工具用。删旧选项比加新功能重要,但工程上几乎总被低优先级。
- 椭圆曲线赢在数学结构。NFS 在曲线上失效不是巧合,是椭圆曲线离散对数问题(ECDLP)没有”子指数”算法——这是 [[tls-1.3]] 强制 ECDHE 的根本理由。
- “今天的密文是明天的明文”。国家级对手会先存后解,密码体系的安全裕度必须按 10-30 年算,不是按今天的算力。这条逻辑现在又驱动着 PQC 标准化。
延伸阅读
- Imperfect Forward Secrecy CCS 2015 PDF —— 原始论文,13 页,三作者面向工程师写得算友好
- weakdh.org —— 项目页,含在线检测工具和披露时间线
- CACM 2019 扩展版 —— 加了对 NSA 文件的详细比对
- RFC 7919 —— “Negotiated Finite Field DH Ephemeral Parameters for TLS”,Logjam 的标准化回应
- diffie-hellman-1976 —— 协议数学基础,理解 Logjam 必读
- [[tls-1.3]] —— Logjam 的最终修复方案
- heartbleed-2014 —— 同期的另一个 TLS 大事件,对照 “实现 bug vs 标准 bug” 的差别
关联
- diffie-hellman-1976 —— Logjam 攻击的就是 1976 年这套协议的工程实现
- [[tls-1.3]] —— 砍掉 finite-field DH 的最终成品,Logjam 是直接动因
- heartbleed-2014 —— 2014 年的实现 bug,与 Logjam 形成 “实现 vs 标准” 对照
- lucky13-2013 —— 同期 TLS 攻击,针对的是 MAC-then-encrypt 模式
- aes —— 对称加密在 Logjam 里没问题,问题全在密钥协商一侧
- diffie-hellman —— 概念入门页,理解协议本身后再读 Logjam 的攻击思路
反向链接
- amplification-hell-2014 —— Amplification Hell 2014 — 把家用宽带放大成几百 Gbps 的反射攻击
- diffie-hellman —— Diffie-Hellman 密钥交换
- lucky13-2013 —— Lucky 13 — 用毫秒级时间差把 TLS 加密看穿