eMudhra 弱密钥事件:私钥可从公开证书恢复,证书链该怎么排查
Cloudflare 复盘了 eMudhra 八把弱中间密钥事件:受影响私钥可从公开证书近乎即时恢复,不强制证书透明度的客户端会接受伪造证书。截至 2026 年 10 月 30 日,Cloudflare 记录约 22,000 次使用弱密钥的握手尝试,并拒绝了所有需要验证证书的握手;原文称尚未发现弱密钥被用于成功拦截其连接的证据。访客端探针显示现代浏览器多已修补,Android WebView 仍有 30–40% 接受,大型网络中超过一半探针仍接受受损链。
2026 年 10 月 19 日,Cloudflare 获悉 eMudhra 签发的八把中间证书私钥强度极弱,其中一把的取值就是 4。由于这些私钥可以从公开证书里近乎即时地恢复,任何仍信任这些中间证书、又不强制证书透明度(Certificate Transparency,CT)的客户端,都会接受攻击者为任意域名伪造的证书。Cloudflare 在 10 月 30 日的复盘文章中给出了修补过程、利用迹象与访客端修补进度(来源)。对开发者而言,可操作的结论有三条:清点信任存储、确认是否强制 CT、检查自己的服务端是否在用这些证书。以下事实均出自该文;本文没有核验材料之外的信息。
事件本身:八把可从公开证书恢复的中间私钥#
按原文描述,eMudhra 本应为一个“虚拟密码锁”挑选一个 115 位数字,实际挑的是 4;另外七把密钥的取值分别是 56、66、115、155、156、230、237。原文称这八把密钥“弱得令人震惊”。这里的 115 既是“115 位数字”的描述,也恰好是一把密钥的取值,属于原文给出的两组事实。
原文特别对比了历史事件:DigiNotar、TÜRKTRUST、TrustWave 等 CA 被攻破时,密钥访问权限在一定程度上是被限制的,只有有限的一组攻击者或组织能签发欺诈证书;eMudhra 这次不同,受影响的中间私钥可以从公开证书本身几乎瞬间恢复,任何人都能独立恢复同一把签名密钥,并为任意域名签发证书——前提是客户端不强制证书透明度,且仍然信任这些中间证书。
eMudhra 已宣布退出公共 CA 业务,并把原因归结为密钥生成脚本的错误,但尚未公开该脚本。原文还记录了一个细节:eMudhra 先用一把可能是正确生成的密钥签发了证书吊销列表(CRL),随后又改成用弱密钥签发。这一反复为何没有触发告警、审计方与交叉签名方各自承担什么角色,原文列为尚待厘清的问题。
Cloudflare 的处置过程:可作为修复优先级的参考#
Cloudflare 在 10 月 19 日当天开始修补高影响系统,其中包括用 Pingora 编写的、面向客户源站的代理。该代理承担 Cloudflare 大部分出站连接,在数小时内被改为拒绝这些存在弱点的密钥。与此同时,Cloudflare 借助 AI 辅助分析源代码,在 4 小时内完成对所有仍信任这些弱密钥的系统的完整分析;它为每个系统建立工单并附上初步分析,要求团队在当天结束前确认或修正分析结论,高影响系统立即修补,低影响系统则限期在“上周底”前完成。原文写作时,所有高优先级系统已修补,少量已确认低影响的工单仍在处理。
10 月 21 日,Pingora 的日志上报上线,用于记录任何出示由 eMudhra 弱密钥签发证书的握手。由于该出站服务覆盖了 Cloudflare 机器绝大多数对外 TLS 连接,这一层日志是后续观测利用迹象的基础。
利用迹象:约 22,000 次握手能说明什么#
日志上线约一周后,Cloudflare 记录到约 22,000 次使用弱 eMudhra 密钥的握手尝试。其中三分之二是对 emudhra.we-have-a-problem.com 这类测试站点的抓取;剩下的几乎全部指向那些“用弱中间证书给自己签了证书”的源站。所有配置了证书验证的握手都被拒绝。
约 160 次握手值得单独看:这些证书的 SAN(Subject Alternative Name,主体备用名)指向与握手请求的 SNI 无关的其他组织域名,部分涉及消费级 IoT 设备相关域名;这些伪造证书是在密钥泄露之后制作的,有的有效期超过两年,长于公共 CA 允许签发的期限。但 Cloudflare 判断它们更像服务器自身的默认证书,而非拦截尝试:证书里的域名与正在连接的主机不一致,主机名验证本来就会失败;而且在多个地点看到同一张证书,说明它来自服务器本身,而不是某条网络路径上的中间人。
时间上,Cloudflare 看到的一张伪造证书日期为 10 月 20 日 18:19 UTC,距 Mozilla 的 bug 报告公开不到一小时。这说明在弱点公开后数小时内,已经有人用这些密钥签发证书。
结论的边界需要说清楚:原文称目前没有证据表明这些弱密钥被用于拦截 Cloudflare 的连接,但这不排除经过精心定向的拦截;后者只能依靠系统被入侵的常规间接信号判断,而原文称尚未看到这类信号。
访客端修补:探针方法能测什么、不能测什么#
Cloudflare 无法在不破坏连接的前提下直接测试访客是否仍信任弱密钥,于是改在 challenge 页面上发探针:在部分 challenge 页面中发送两个探测连接,一个指向安装了 eMudhra 签名证书的 ca1.cloudflarecaptcha.com,一个指向使用正常签名证书的 ca2.cloudflarecaptcha.com 作对照,然后记录探测是否成功。一周内约做了 5000 万次探针。
原文给出的前提偏差很重要:challenge 页面的流量高度偏斜,其中包含大量未确认的 bot;并且只有执行 JavaScript 的客户端才会发出探针。因此样本不等于全体互联网客户端。
实验期间有几次 UTC 时间上的改动:10 月 23 日 15:30,控制端点也改为提供 eMudhra 证书但不带 SCT(签名证书时间戳);10 月 23 日 16:30,challenge 平台因一个无关问题回滚,探针在 10 月 27 日 10:00 才恢复;10 月 27 日 16:37,补上了并非所有客户端都认识的 G3 交叉签名,并从两个端点移除 SCT;16:49 把 ca2 切换到 AAA Certificate Services 根;18:18 探针覆盖范围从 1% 提高到非付费客户区 challenge 页面的 10%。
结果大致是:较新的现代浏览器大多已修补,bot 和旧浏览器没有;嵌入式浏览器如 Android WebView 落后,仍有 30–40% 接受。首个周末(存在监控缺口)能看到明显的修补迹象,之后几乎不再变化。10 月 29 日 18:00 UTC 起,大量自称 Chrome 150–154、运行在 macOS 上的 bot 流量会让图表看起来像在修补,但原文说明这是流量分类变化,同一批 user agent 在带 bot 信号的流量里接受率相应上升。Chrome 150–154 on Linux 是例外,接受率持续下降,但原文称这一证据是提示性而非结论性的。按网络(ASN)拆分,大型网络中超过一半探针仍接受受损链,无论是否带 bot 信号;周末之后趋势持平。
开发者排查清单#
下面这张表把原文事实转换成可执行的检查项,属于建议,不是原文逐条列出的步骤。
| 检查项 | 为什么 | 怎么查 |
|---|---|---|
| 信任存储中是否仍包含 eMudhra 相关中间或根证书 | 只要仍信任,就可能接受用这些密钥伪造的证书 | 检查系统 CA bundle、语言运行时自带证书包、容器基础镜像、被硬编码进代码的证书 |
| 客户端是否强制证书透明度 | 原文明确:不强制 CT 的客户端会接受伪造证书 | 核对 TLS 库配置与策略,而不是只看浏览器版本 |
| 服务端是否在用 eMudhra 签发的证书作默认证书 | 原文观测到约三分之一握手属于源站给自己配了这类证书 | 列出所有对外证书及其签发链 |
| 完整证书链与交叉签名 | 探针结果显示是否带 G3 交叉签名、挂到哪个根,会影响接受率 | 用工具打印完整链,逐个看 issuer |
| 吊销信息能否快速更新 | 原文提到 CRL 的签名密钥本身经历过反复;并主张信任存储不应是静态根列表 | 评估能否不发版就更新吊销与 CT 相关信息 |
| 出站连接是否记录出示特定中间证书的握手 | 这是 Cloudflare 观测利用迹象的手段 | 在代理或 TLS 客户端加日志与告警 |
一个检查证书链的示例(未执行)#
下面的命令是通用做法示例,本次写作未执行;输出取决于你的系统、TLS 库和证书路径,需自行核实。示例域名使用 example.com 作为占位。
# 打印对端送来的完整证书链,逐张看 issuer / subject
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
# 在常见 Linux 路径下粗查本地证书包是否含相关字样(路径并非通用)
grep -ril "emudhra" /etc/ssl/certs/ 2>/dev/null
第一条命令只反映该端点当时送出的链,不代表你的信任存储;第二条依赖发行版的证书目录布局,在部分环境(如容器、自行打包的运行时、macOS 与 Windows 的系统存储)并不适用。更可靠的做法是从你实际使用的运行时读取它加载的证书集合。
边界与待核实项#
- Cloudflare 的 22,000 次握手与 5000 万次探针都来自其自身网络与 challenge 页面,不能外推为全互联网的比例;原文自己也强调探针流量被 bot 严重偏斜。
- eMudhra 的密钥生成脚本尚未公开,脚本错在哪里、审计与交叉签名方的责任,本次材料未提供结论。
- 原文提到 Dennis Jackson 维护的众包修补指引网站,以及主张信任存储需支持快速更新的 upki 项目,但本次材料未给出这两个地址,需自行核实后再使用。
- 若你使用 Cloudflare 的 WARP、Tunnel 等产品,原文指向其上一篇博客说明的客户端侧操作;该篇内容不在本次材料范围内。
把这件事压缩成一句可执行的话:证书链排查的重点不只是“我的站点用了哪张证书”,还包括“我的客户端还愿意相信谁”。前者决定你会不会对外出示一张已被攻破的证书,后者决定别人能不能在你面前冒充任何站点。
常见问题(FAQ)
这次事件和过去 CA 被攻破有什么不同?
Cloudflare 是否被成功拦截?
现在最该做什么?
参考来源
以上为本文写作时的参考资料,引用观点以原文为准。