用户登录

技术文章

外部链接将在新标签页打开。

证书弱密钥的利用与修补追踪:以 eMudhra 事件为例,从“少数密钥”反推轮换与取证顺序

一句话回答

Cloudflare 复盘显示,eMudhra 的八个中间证书私钥弱到可从公开证书恢复,任何未修补且不强制 CT 的客户端都可能接受伪造证书。文章据此梳理一条可复用的顺序:先在出站路径拒绝受损链,再清点信任面,然后铺设日志,最后才用抽样探测估计修补进度;取证结论必须标注样本偏差与阴性证据的边界。

核心要点 TL;DR
  • 弱密钥的风险不在于“泄露规模”,而在于私钥可从公开证书重建,攻击者不需要入侵 CA。
  • Cloudflare 的顺序是先切断出站验证、再清点信任面、再铺日志、最后做访客侧抽样,统计放在修补之后。
  • ,000 次弱密钥握手尝试中约 160 次 SAN 与 SNI 不符,但证据指向源站自带默认证书,而非路径中间人。
  • 挑战页探测受机器人、仅 JS 客户端、端点变更与覆盖比例变化影响,不能直接读成全网修补进度。

Cloudflare 在 2026 年 10 月 30 日的复盘中给出的数字是八个:4、56、66、115、155、156、230、237。它们是 eMudhra 中间证书的私钥取值,弱到 Cloudflare 的说法是“任何人都能从公开证书里几乎立即恢复这些签名密钥”,进而为任意域名签发证书——前提是客户端尚未修补,且不强制证书透明度(Certificate Transparency,CT)。(来源:Cloudflare Blog,2026-10-30)所以这里真正要回答的不是“泄露了几把钥匙”,而是:当密钥空间小到可以枚举时,轮换与取证该按什么顺序做。

先分清三类陈述#

这个话题里混着三种不同强度的信息,混用会让结论失真。

  • 来源方观测:Cloudflare 在自己网络内看到的握手尝试、伪造证书时间戳、挑战页探测比例。它有明确的作用域,只代表经过 Cloudflare 的那部分流量。
  • 当事方声明:eMudhra 宣布退出公共 CA 业务,并称问题来自密钥生成脚本的错误,但没有公开该脚本。这是声明,不是已验证的根因。
  • 待核实:审计方与交叉签名方在事件中的角色,Cloudflare 明确说“尚待厘清”;八个密钥对应的证书清单与指纹,本次材料也未提供。

还有一处细节值得单独标记:Cloudflare 称 eMudhra 曾用“可能是正确生成的密钥”签发过一份证书吊销列表(CRL),随后又改为用弱密钥签。这个反复本身就是取证线索,但 Cloudflare 的措辞是推测性的,不宜当作定论。

为什么“少数密钥”改变了威胁模型#

过去的 CA 事故——DigiNotar、TÜRKTRUST、TrustWave——共同点是签发能力被入侵,能滥用它的攻击者或组织在某种程度上是有限的。eMudhra 这次不同:受影响的中间私钥可由任何人独立恢复,不需要先攻破任何系统,也不需要谁授权。Cloudflare 的对比很直接:前者是“少数人获得签发能力”,后者是“所有人都有签发能力”。

这直接改变了轮换与吊销的时序假设。吊销依赖列表传播,天然有延迟;而从公开证书重建私钥没有延迟。因此不能把“已提交吊销”当作缓解措施,必须在验证路径上先做拒绝。

从 Cloudflare 的自述反推修补顺序#

以下是 Cloudflare 针对自身架构的处置,不是通用模板;其中“四小时完成源码全量分析”属于来源方自述,未独立验证。

时间动作性质
10 月 19 日得知八个弱密钥,当天开始修补高影响系统;Pingora 出站代理数小时内改为拒绝受损链切断
10 月 19 日起AI 辅助分析源码,四小时内找出其他信任这些弱密钥的系统,逐系统开票并要求当天确认清点
10 月 21 日Pingora 日志铺开完成,开始记录使用弱密钥的握手观测
10 月 20 日 18:19 UTC观测到的一张伪造证书日期,距 Mozilla 缺陷报告公开不到一小时取证
10 月 23 日 15:30 / 16:30控制端点改配无 SCT 的 eMudhra 证书;挑战平台因无关问题回滚,探测中断测量变更
10 月 27 日 10:00–18:18探测恢复;补上 G3 交叉签名并移除 SCT;ca2 改链到 AAA Certificate Services 根;探测比例从 1% 提到非付费区的 10%测量变更
10 月 29 日 18:00 UTC上线检测,识别出大量冒充 macOS Chrome 150–154 的机器人流量校正

第一层:在出站路径上先拒绝

Pingora 承担 Cloudflare 绝大部分出站连接,优先在这里拒绝,是因为出站连接是主动发起验证的一方,拒绝的代价可控、生效快。这一步在取证之前完成,不是顺序颠倒,而是让后续计数有意义。

第二层:清点信任面

只修一个组件没有意义,因为弱密钥可能被多处信任存储引用。Cloudflare 用源码分析找全量引用点,按影响分级开票:高影响立即修,低影响限期修。这里的可复用点是“先枚举引用点,再排优先级”,而不是具体的分析手段。

第三层:把“有没有人用”变成可计数

日志铺开是在拒绝逻辑之后。这个顺序保证计数期间不会真的接受伪造链,也避免把正常验证失败与攻击尝试混为一谈。

第四层:访客侧只能间接测

Cloudflare 无法直接测试访客是否仍信任弱密钥——直接测会中断连接。它的做法是在一部分挑战页面上发起两个探测:一个指向装有 eMudhra 证书的端点,一个指向正常签名证书的对照端点,记录探测是否成功。一周内约 5,000 万次探测。

取证:22,000 次尝试怎么分级#

一周内 Cloudflare 记录到约 22,000 次使用弱 eMudhra 密钥的握手尝试,并且全部被拒绝。分级方式值得借鉴:

  • 约三分之二是对测试站点的抓取,例如 emudhra.we-have-a-problem.com。
  • 剩余部分几乎都指向那些看起来给自己签了一张证书的源站。
  • 约 160 次值得单独看:证书的 SAN 指向与 SNI 无关的其他组织域名,部分是消费级物联网设备域名,有效期超过两年——长于任何公共 CA 可签发的期限。

关键判断在于:这些证书更像是服务器自带的默认证书,而不是拦截链的一环。理由是域名与被连接的主机不匹配,主机名验证本来就会失败;而且多个探测位置收到同一张证书,说明它来自服务器自身,而非某条网络路径上的中间人。因此 Cloudflare 的结论是“尚无拦截证据”,但同一批数据也证明伪造行为在弱点公开后一小时内就出现了——这只能排除大规模拦截,不能排除精心定向的拦截,后者要靠系统入侵的常规间接信号,目前未见。

修补追踪里的五个偏差#

访客侧数据在发布时就带着一串限定条件,读曲线前要先对齐口径:

  1. 样本偏斜:挑战页流量里混有大量未确认的机器人,且只有执行 JavaScript 的客户端才会发出探测。
  2. 端点定义变更:10 月 23 日控制端点也改为提供无 SCT 的 eMudhra 证书,两次测量并不可直接比较。
  3. 监控缺口:10 月 23 日 16:30 到 10 月 27 日 10:00 探测中断,第一个周末的“修补证据”要打折看。
  4. 分类变化伪装成修补:10 月 29 日上线的机器人检测让自称 macOS Chrome 150–154 的流量重新归类,图上看起来像接受率下降,实际是同一批 UA 在机器人信号分组里接受率上升。
  5. 覆盖比例变化:10 月 27 日 18:18 探测从 1% 提升到非付费客户区域的 10%,样本构成随之改变。

在这些限定之下,可说的结论是:较新的现代浏览器大多已修补,机器人与旧浏览器没有;嵌入式浏览器如 Android WebView 落后,仍有 30–40% 接受;按网络(ASN)看,大型网络中超过一半探测仍接受受损链。这是 Cloudflare 视角下的估计,不是全网普查。

给开发者的检查顺序#

以下顺序由上述材料推出,属于建议而非已验证的通用流程:

  1. 确认自己的客户端信任存储与出站验证配置是否引用了受损中间证书,先枚举引用点。
  2. 对已知受损链做显式拒绝,不等待吊销列表传播到位。
  3. 如果运行源站,检查默认证书是否被替换为异常证书——那 160 次握手的形态说明这类替换确实会发生。
  4. 单独验证吊销信息的可信度:eMudhra 的 CRL 曾出现签名密钥反复,这说明“吊销”本身也需要核实。
  5. 把信任存储当作可快速更新的数据,而不只是静态根证书列表;Cloudflare 提到的 upki 一类项目正是这个方向。
  6. 更新客户端;嵌入式 WebView 需要单列排期,它的修补明显滞后。

下面只是检查顺序的示意,未实际执行,域名与指纹均为占位:

# 未执行示例:逐张取出链中证书的 SHA-256 指纹,再与拒绝列表比对
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null 2>/dev/null \
  | awk 'BEGIN{n=0} /BEGIN CERT/{n++} {print > ("chain-" n ".pem")}'
for f in chain-*.pem; do
  openssl x509 -in "$f" -noout -fingerprint -sha256
done

这段脚本只解决“我这边的链里有没有已知受损证书”,不解决“对方是否信任我”。后者只能像 Cloudflare 那样做双端点抽样,并且明确记录样本偏差。

还没有答案的部分#

  • eMudhra 声称的密钥生成脚本错误,脚本本身未公开,根因仍待核实。
  • 审计方与交叉签名方的角色,Cloudflare 只说“需要厘清”。
  • 八个弱密钥对应的完整证书清单与指纹,本次材料未提供,因此无法直接用于构建拒绝列表。
  • 除 Cloudflare 观测范围之外的全网修补比例,待核实。

如果你的服务通过 TLS 调用第三方 API,这套顺序同样成立:先收紧出站验证,再清点还有哪些组件信任同一条链,最后才谈统计。统计放在修补之后,才不至于把“我们拒绝了”误读成“没人尝试过”。

常见问题(FAQ)

弱密钥和私钥泄露有什么区别?
私钥泄露意味着攻击者拿到了某一份材料;弱密钥意味着材料本身可以被枚举或推算。Cloudflare 指出 eMudhra 的中间私钥可由任何人从公开证书几乎立即恢复,因此不存在“只有拿到文件的人才能签发”这一层限制。
为什么先修补、后统计?
未修补时,日志里的握手失败既可能来自攻击尝试,也可能来自正常验证拒绝,混在一起难以归因。Cloudflare 先让 Pingora 拒绝受损链,再铺日志计数,之后的数据才对应“被拒绝的尝试”。
看到接受率下降就能说明修补完成了吗?
不能。Cloudflare 记录了端点定义变更、监控缺口、探测比例从 1% 提到 10%,以及 10 月 29 日机器人流量分类变化造成的假性下降。读这类曲线要先对齐测量口径。

参考来源

  1. 4 real? Tracking exploitation and patching of eMudhra’s weak keys

以上为本文写作时的参考资料,引用观点以原文为准。

作者:沐小悠

本文约 10 分钟读完 · 关键词:eMudhra 弱密钥、中间证书轮换、证书吊销、证书透明度、TLS 信任链

更多文章 GET 示例接口

「」标签下的其他文章