修补窗口内如何界定残余暴露:eMudhra 弱密钥事件的探针口径与判定条件
修补窗口内的残余暴露不能用一个比例概括,应拆成出站信任、入站证书与第三方客户端三条路径:前两条可以穷举并写成判定条件,第三条只能抽样估计。Cloudflare 用挑战页探针测量访客侧信任状态,但流量构成、控制端点变更、监控中断与采样比例调整都会把口径变化伪装成修补进展,因此结论应表述为带条件的区间而非单一数字。
- 残余暴露至少分三类:我方作为客户端是否仍信任弱密钥、我方作为服务器是否持有弱中间签发的证书、下游客户端是否仍接受该链。前
- Cloudflare 的探针数据里,UA 接受率的变化有两类来源:真实的客户端更新,以及流量分类规则的变更;10 月 2
- 对出站连接的判定应落在“放行数量”上而不是“拒绝数量”上:拒绝是预期行为,放行才是缺陷。
- eMudhra 的密钥生成脚本未公开,审计方与交叉签名方的角色尚未澄清;这些归因在材料中仍属待核实。
修补窗口内的“残余暴露”很难用一个百分比说清。更可操作的做法是把它拆成三条互不替代的路径:我方作为客户端是否仍信任弱密钥、我方作为服务器是否持有弱中间签发的证书、下游客户端是否仍接受这条链。前两条可以穷举,也能写成可复核的判定条件;第三条只能抽样估计,而抽样的口径一旦变化,看起来就像修补有了进展。Cloudflare 在 2026 年 10 月底公布的追踪数据,正好把这三条路径的可观测性与天花板都暴露了出来(Cloudflare Blog,2026-10-30)。
先澄清一处容易被标题带偏的事实#
该事件的弱密钥并不是四个。按来源的列举,eMudhra 一共有八个弱密钥,取值分别是 4、56、66、115、155、156、230 和 237;标题里的“Four, just four”指的是其中一个密钥的取值就是数字 4,而不是只有四个密钥。这个细节值得先固定下来,因为它决定了后续排查时匹配的是八个密钥标识,不是一个。
与历史上密钥泄露的 CA 事件相比,这次的特殊之处在于恢复成本:受影响的中间 CA 私钥可以从公开证书中几乎即时恢复,任何拿到这些密钥的人都能为任意域名签发证书,只要目标客户端不强制证书透明度(Certificate Transparency,CT)就会接受。这意味着“漏了哪张证书”不是主要问题,“谁的信任库里还留着这条链”才是。
可以穷举的两条路径#
第一条是我方作为客户端的出站信任。Cloudflare 在 2026 年 10 月 19 日当天开始修补高影响系统,其中包括承担大部分出站连接的 Pingora 代理,数小时内改为拒绝这批弱密钥;同一时间用 AI 辅助分析源码,四小时内列出所有信任这些密钥的系统,并给每个系统建单,要求当天确认或修正分析结论。10 月 21 日,用于记录“对端出示弱密钥签名证书”的日志完成上线。
第二条是我方作为服务器的入站证书。这条路径不需要推断,只需要枚举:列出所有由相关中间 CA 签发的证书,逐张核对签发链与有效期,然后替换。它的判定条件是二值的,不存在抽样误差。
第一条路径真正的判定信号不是“拒绝了多少次”,而是“有没有放行”。拒绝是修补生效后的预期行为,放行才是缺陷。如果把拒绝计数当成风险指标,修补越成功,数字越难看,结论会完全反过来。下面是一段未执行的示例,只说明日志需要保留哪些字段,不代表任何真实系统的实现。
# 未执行的示例(伪代码):判定一条出站握手属于哪一类
record = {
"sni": ..., # 客户端请求的主机名
"chain_spki": [...], # 对端证书链上每张证书的 SPKI 指纹
"verification": "enforced", # 是否强制执行证书验证
"outcome": "ok" | "rejected" | "ACCEPTED_WEAK_KEY",
}
# 关键不是统计 rejected 的数量,而是 ACCEPTED_WEAK_KEY 是否为 0
按来源披露,截至 Cloudflare 发文时,日志上线约一周共记录到约 22,000 次使用弱 eMudhra 密钥的握手尝试;其中约三分之二是对测试站点 emudhra.we-have-a-problem.com 的抓取,剩余近三分之一大多指向使用弱中间证书给自己签发证书的源站。所有启用了证书验证的握手都被拒绝。这一组数字的意义在于:拒绝侧是预期内的,真正需要解释的是那约 160 次异常握手。
只能抽样的一条路径:访客端的信任状态#
下游客户端无法穷举。直接测试访客是否还信任弱密钥,意味着主动向对方出示一张弱密钥签发的证书;如果对方仍信任,连接会在无告警的情况下建立。Cloudflare 的做法是在一部分挑战页面上向两个端点各发一个探针:ca1.cloudflarecaptcha.com 装 eMudhra 证书,ca2.cloudflarecaptcha.com 装正常证书作为对照,然后记录成功率。一周内约 5,000 万次探针。
这个设计本身是合理的,但它有三个无法通过增大样本消除的偏差,来源也明确承认了前两个:挑战页面流量按设计高度偏斜,其中包含大量未经确认的 bot;只有执行 JavaScript 的客户端才会发出探针;以及第三个——观察期内控制端点被多次改动,基线并不稳定。
四个会把口径变化读成“修补进展”的陷阱#
来源给出了完整的改动时间线(均为 UTC):10 月 23 日 15:30,控制端点也改为提供 eMudhra 证书但不带签名证书时间戳(SCT);10 月 23 日 16:30,挑战平台因无关问题回滚,探针直到 10 月 27 日 10:00 才恢复;10 月 27 日 16:37,补上此前遗漏的 G3 交叉签名并从两个端点移除 SCT;16:49 将 ca2 改为链到 AAA Certificate Services 根;18:18 把非付费客户 zone 的探针比例从 1% 提升到 10%。任何一条都足以让接受率曲线跳变。
最能说明问题的是 10 月 29 日 18:00 上线的检测:它抓到大量自称 macOS 上 Chrome 150–154 的 bot 流量。在总体曲线上,这一段看起来像修补加速,但实际上是流量分类规则变了——同一批 User-Agent 在“检出 bot 信号”的流量里接受率同步上升。Linux 上的 Chrome 150–154 是例外,接受率持续下降,与真实的进一步修补一致,但来源自己把这一证据定位为提示性而非结论性。
| 观测到的现象 | 需要先排除的解释 | 排除后才能下的结论 |
|---|---|---|
| 某 UA 段接受率突然下降 | 流量分类规则变更、采样比例从 1% 调到 10% | 该 UA 对应的客户端软件确实在更新 |
| 周末之后整体曲线走平 | 10 月 23 日至 27 日的探针中断造成样本缺口 | 修补动力衰减 |
| 某 ASN 接受率高于均值 | 该网络中 bot 与嵌入式浏览器占比不同 | 该网络的管理策略存在问题 |
| 探针接受率整体偏低 | 只有执行 JavaScript 的客户端会发探针 | 全体访客都已修补 |
把残余暴露写成判定条件#
- 出站信任按密钥标识匹配,不按名称匹配。用证书的 SPKI 指纹或密钥指纹做集合比对,避免受主体名称字符串差异影响。
- 把“放行数”设为零容忍指标。拒绝计数只用于确认日志在工作,不作为风险下降的证据。
- 入站证书用清单核对,不靠抽查。签发链、有效期、是否带 SCT 三条同时记录,缺失项单列。
- 第三方侧只报区间与条件。例如“在启用 JavaScript 且未检出 bot 信号的挑战页流量中,接受率约为某个区间”,并同时给出样本时间窗与端点配置。
- 每次改动端点配置都重设基线。更换证书链、增删 SCT、切换根证书都会改变接受率的绝对值,跨改动点连线没有意义。
现在能说到哪一步#
按来源数据,按网络(ASN)拆分后,大型网络中超过一半的探针仍然接受这条受损链,无论是否检出 bot 信号;嵌入式浏览器如 Android WebView 有 30%–40% 仍接受;第一个周末能看到明显的修补迹象,之后几乎没有移动。这几个数字描述的是挑战页流量的接受率,不能直接换算成“互联网上还有多少比例的设备存在风险”,也不能据此推断某个具体组织的暴露程度。
伪造侧的迹象更值得注意:约 160 次握手使用了 SAN 指向其他组织域名的证书,部分域名与消费级 IoT 设备相关;有的证书在密钥公开后签发,有效期超过两年,长于公共 CA 允许的期限;其中一张的签发时间为 2026 年 10 月 20 日 18:19 UTC,距 Mozilla 的 bug 报告公开不到一小时。但来源同时指出,这些证书更像服务器自带的默认证书,而非针对 Cloudflare 的拦截尝试——它们指向的域名与请求的 SNI 不同,本来就会在主机名验证阶段失败,且同一张证书在多个位置被看到,说明它来自服务器本身而不是某条网络路径上的中间人。截至发文,Cloudflare 未观察到弱密钥被用于拦截其连接的证据,但来源也明确表示这不排除精心定向的拦截,相关判断依赖常规的系统失陷间接信号,目前未出现。
为什么吊销不能只靠“发一份 CRL”#
这起事件里有一个细节值得单独记住:来源称 eMudhra 用一份可能是正确生成的密钥签署了证书吊销列表(CRL),随后又将其更正为用弱密钥签署。同一份材料还提到,eMudhra 已宣布退出公共 CA 业务,声称问题出在密钥生成脚本,但尚未公开该脚本;审计方与交叉签名方在此事中的角色也仍待澄清。这些都属于待核实的归因,不能当作已确认的结论使用。
可确认的部分是结构性的:如果信任库只是一份静态的根证书列表,那么吊销的速度上限就取决于列表更新周期。Cloudflare 提到其部分产品已有快速吊销机制,并看好 upki 这类把吊销信息与 CT 密钥纳入可快速更新的信任数据的项目。对开发者而言,这条线索的落点是:在自己的出站信任配置里,吊销与信任更新的路径是否独立于版本发布周期——如果不是,修补窗口的长度就不由你决定。
结论#
回到标题的问题:修补窗口内的残余暴露,应当被界定为三条路径的分别结论——出站信任是否还有放行、入站证书清单是否清零、第三方接受率的区间与适用条件。前两条可以给出确定的答案,第三条只能给出带口径的估计。而任何一条估计,在跨过端点配置变更、监控中断或采样比例调整之后,都需要重新起算,否则那些本属于测量方式的跳变,会被误读成修补的进展。
常见问题(FAQ)
探针显示某类客户端仍接受弱密钥,是否意味着该网络正在被拦截?
为什么不能直接测试访客是否还信任弱密钥?
到底是四个弱密钥还是八个?
参考来源
以上为本文写作时的参考资料,引用观点以原文为准。