印度三哥骚操作,闯大祸了,外网HTTPS 差点集体失守
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
QUOTE 真正的问题不是私钥被偷了,而是它根本没被保密过 —— 整整 17 个月,8 个 bit 撑起了整条信任链。 —— 事件时间 2026 年 10 月 17 日起 10 月 17 日晚上,一个署名 Wayne 的研究员,给 Chrome、Mozilla、Apple、微软这四个根证书项目同时发了一封邮件,说印度一家叫 eMudhra 的证书颁发机构,有 8 张中间证书的私钥出事了。 他附上了证据 —— 用这 8 个私钥,分别对同一句话做了签名。 三天后,这 8 个私钥的数值被公开了: 4 、56、66、115、155、156、230、237。 这里得稍微解释一下,中间 CA 是干什么的。 根证书相当于「总行」,中间 CA 就是「分行」。它自己不会出现在你浏览器里看到的那张证书上,但它手里攥着的私钥,能给它签发的 任意域名 背书。所以中间 CA 出事,动静比根证书小得多,杀伤力却一点不差 —— 攻击者拿着它的私钥,可以给包括银行在内的任何站点签一张浏览器完全信任的证书,而用户地址栏里那个「小锁」,不会有任何异常。 eMudhra 是印度班加罗尔的老牌 CA,公司自己宣称累计签发过 6000 万张以上 证书。这次出事的 8 张,属于其 emSign 品牌下的中间 CA。 10 月 21 日,也就是事件公开发酵的第二天,eMudhra 股价在印度市场直接 20% 跌停 ,从 540 卢比跌到 432 卢比,是它上市以来最大单日跌幅,距离 2024 年 12 月 1024 卢比的历史高点已经跌去近六成。10 月 22 日,公司董事会决定,彻底退出全球 SSL/TLS 证书业务。 不过这事儿最离谱的地方,其实不是跌停。 本文看点 01 8 张证书,8 个数字 02 一次 KGC 手滑,错了 17 个月 03 浏览器 3 小时拉黑,固件要等到 2039 01 THE INCIDENT 这 8 张证书是 2025 年 4 月 30 日生成的,涵盖 DV、OV、EV 三种类型的 TLS 证书各两代,外加两张 OV 代码签名证书。它们链到 emSign Root TLS CA - G3 这类全球浏览器根信任库里的根上,还被 Sectigo 用它更老的 AAA Certificate Services 根交叉签过一遍。 安全研究员 Scott Helme 后来把 Mozilla 附在公告里的 16 张证书(8 个私钥,每个被 eMudhra 和 Sectigo 各签了一次)全拉下来暴力枚举了一遍,结果是 无一幸免 。这就是那张著名的对照表: — Scott Helme 恢复出的 8 个私钥数值与中间 CA 对应关系(截图自其博客) 其中 EM OV TLS CA - G3C 的私钥,就是 4。这张证书是张 OV(组织验证) 签发 CA —— 也就是说,它本来是拿来给企业网站签发带企业身份的证书的。 再看一眼时间线,这事儿有多快、多乱: 而这 8 张证书的具体指纹、序列号、签发者,官方公告里都列得清清楚楚: — 8 张受影响中间 CA 的序列号与指纹清单(截图自 Mozilla 事件报告) 顺便一提,Wayne 这位研究员除了一个署名和一句被签了 8 次的话,几乎没留下更多信息。倒是另外一位安全研究员 Flüpke,把其中一个私钥直接贴到了 GitHub 上。 02 HOW A KEY BECOMES 4 这些证书用的是 P-384 椭圆曲线 。在椭圆曲线里,私钥其实就是一个数字,记作 d;公钥是证书里给全世界看的那个东西,它等于 d 乘以一个固定的曲线基点 G。 正向算很容易, 反过来从公钥推回 d 则是被认为做不到的 —— 这就是整个安全模型的立足点。但这个立足点有个前提:d 必须足够大。正常的 P-384 私钥应该是 384 位随机数,也就是 2³⁸⁴ 种可能(约 10¹¹⁵ 种),谁也不可能去穷举。 而 eMudhra 这批密钥长这样: — 原文对照图:eMudhra 的密钥与正常 P-384 密钥(截图自 Scott Helme 博客) 那怎么把它还原出来? 一个字节只有 256 种可能 ,所以搜索就是:算 1×G、2×G、3×G…… 一直算到跟证书里的公钥对上为止, 最多 255 步 。 Scott Helme 自己的说法是:他在自己笔记本上把这 8 个私钥全恢复出来, 用时不到一秒 。Mozilla 那边更快,收到报告后 1 小时 42 分钟就自己独立复现了一遍。 最让人后背发凉的地方在这儿 —— 这些证书 看起来完全正常 。由 d=4 导出的公钥是曲线上的一个合法点,编码正确、曲线正确、参数合法,所有结构性检查全部通过。 「唯一的发现方式,是去试。」 换句话说, 没有任何一个自动化的证书校验环节会发现这件事 。CA 自己验一遍、浏览器收录时验一遍、审计机构来看一遍 —— 全都通过。因为它从数学上就是一把合法的钥匙,只不过这把钥匙的齿太浅了。 03 DISCOVERY 这事儿之所以能一夜之间被整个浏览器生态响应起来,全靠一个很干净的证明方式。 Wayne 用这 8 个私钥 分别签了同一句话 ,然后把证书、公钥、签名打包成一个压缩包提交给根证书项目团队。任何人都能用 OpenSSL 复验这个签名是否成立 —— 如果验得过,就说明对方确实持有对应私钥。这比任何口头描述都有说服力。 — 官方披露页:用私钥签名的那句证明(截图自 emudhra.we-have-a-problem.com) Mozilla 收到报告后 2 分钟就确认了这份证明有效,随后在事件记录里留下了这样一条时间线: — Mozilla 事件记录中的处置时间线(截图自 Bugzilla 2083449) 最关键的一行是 21:48 —— Mozilla 在不依赖报告人任何方法的前提下,独立恢复出了这些私钥 ,从而确认密钥生成流程存在缺陷、且「trivial to exploit」(极易利用)。 同期,Firefox 社区的 Ian Carroll 在邮件列表里留下了一句定性,被广泛引用: 「它们本质上是单字节的弱密钥,任何人都能分解出来,而且这个问题无法被遏制。」 而它无法被遏制的原因,说起来可能会让人后背发凉: 这批私钥从证书诞生的那一刻起,就等同于公开 。 正常的 CA 私钥泄露,至少还有个「小偷」和「某个时刻」可以推理。而这次没有小偷,也就没有「谁在什么时候拿到的」这种问题。 04 ROOT CAUSE eMudhra 在 Mozilla 的公开缺陷跟踪系统上给出了正式说明。要点是这样的:那 8 张证书是在 2025 年 4 月 30 日的密钥生成仪式 (KGC)上批量生成的,用的是符合 FIPS 140-2 Level 3 认证的硬件安全模块(HSM,Utimaco 设备)。 那批 24 张中间 CA 分 A、B、C 三个系列,RSA4096 与 P-384 两种算法,DV、OV、EV、CS 四种用途。出事的是 B 和 C 两个系列的 P-384 密钥 ,RSA 那条路径没受影响。 官方给出的完整归因是这样一段: — eMudhra 在 Mozilla 缺陷跟踪系统上的正式归因说明(截图自 Bugzilla 2083449) 翻译成人话就是五步:① 正常生成了一对强密钥;② 因为这批密钥要导出到美国和欧洲的数据中心(为了解决数据主权问题), 按批准的偏离流程加了一段 wrap/unwrap 测试 ;③ 脚本缺陷导致 HSM 上 额外生成了第二对更弱的密钥 ;④ 因为两对密钥的标签长得太像, 人工选错了那一对 ,用它去生成 CSR,再由自己的根签了字;⑤ 这批 CSR 还被送到 Sectigo 做了交叉签名。 有安全工程师用一句特别形象的话总结过这类事故 —— 每一个运维都有自己版本的故事: REFERENCE 「两个文件分别叫 final 和 final_v2,然后发出去的是错的那个。」这一次,错的那个还顺手被送去做了一次交叉签名。 早在 2025 年年中 ,eMudhra 签发的证书撤销列表(CRL)就出现过签名验证失败,当时作为独立缺陷记录在案(后来以 RESOLVED FIXED 结案)。eMudhra 的解释是:CRL 本来是用强私钥签的,但签名不对,于是改用有问题的那套弱密钥重新签了一遍 —— 这项更正于 2025 年 6 月 6 日完成。 不过 Mozilla 那边对这个时间点还有不同说法,他们提到互联网档案馆的快照显示,这批 P-384 的 CRL 从 5 月 23 日 起就在验证失败。两边说法未完全对齐,但结论方向一致: 这个洞其实早在 17 个月前就自己在日志里喊了一嗓子 ,只是没人把它和后来的事联系起来。Mozilla 的工程师在事件里还专门提了一句:这两件事同时出现在同一批中间 CA 上,「似乎不太可能是巧合」。 05 THE RESPONSE Chrome 根证书项目收到报告后 1 小时 40 分钟,就通过 CRLSet 下发了针对公钥哈希的封锁 —— 因为封锁匹配的是密钥本身,所以 Sectigo 交叉签名的那一份也一并被覆盖, 用户既不需要更新浏览器,也不需要重启 。 — Chrome 官方安全博客的处置公告(截图自 blog.google) 10 月 20 日,Mozilla 直接把 emSign ECC Root CA - G3 这个根整个从 NSS 信任库里摘了出去(NSS 3.131.1),Chrome Root Store v43 也预定在 10 月 27 日移除。 吊销中间证书,只能保护那些 会去看吊销列表 的客户端 —— 而真正的问题恰恰是那些不看的。移除根,才能覆盖到这部分。 Chrome 根项目统计,截至 10 月 21 日,大约 3 万张未过期的预证书 链到这个根上,其中 99.9% 来自 InCommon —— 那是服务美国高校和研究机构的信任联盟。校园门户、图书馆系统、科研数据服务、教学平台的管理员,得赶在浏览器翻脸之前把证书换到别的信任链上。 好消息是,攻击面大概率还没被打开过。 eMudhra 称,这 8 张中间 CA 里只有一张真正上过生产,且 从未签发过任何终端实体证书 。Chrome 也确认:Certificate Transparency 日志里根本没有任何一条链到这 6 张 TLS 中间 CA 的记录 —— 换句话说,对强制 CT 的客户端来说,这批弱私钥基本没派上用场。 06 THE LONG TAIL 如果这篇只写到这里,其实还差点意思。浏览器拉黑只是半场,真正的长尾在后面。 官方为此搭了一个检测站(emudhra.we-have-a-problem.com),用这批出问题的中间 CA 给测试域名签发证书,看谁的客户端还能顺利握手而不报错。它还提供了一个公开统计接口,我抓了一份实时数据: — 官方检测站实时统计:仍在信任失效中间 CA 的客户端 Top 12 看这个排名就很清楚了:排第一的不是浏览器,是 curl (两个版本加起来 46207 次)、 Zabbix (26228 次)、Python-urllib、node。命令行和中间件这一类客户端, 占了全部成功握手的 48% 。 原因也不复杂。curl、Python、Go、Java、git、各种包管理器,它们的 TLS 客户端行为高度趋同:信任磁盘上一份 CA bundle(往往很老)、 默认不查吊销 、也不强制 CT。浏览器那一套 OneCRL / CRLSet 的机制,对它们基本等于不存在。 Scott Helme 自己做了实测:他拿 api.stripe.com 这个域名在本地起了个服务器,用弱私钥签的证书丢进去。结果 curl 输出 SSL certificate verify ok ,Python 握手成功,Node 直接报 authorized: true ,在他测过的每一台 Linux 和 macOS 上都是如此。Windows 上 CryptoAPI 也接受这条链,除非手动打开吊销检查 —— 而开了之后,也只有两条路径中的一条返回了已吊销。 只要你在这条网络路径上,证书里换成什么域名都无所谓 —— 剩下的就只是常规的中间人作业了。 Scott Helme 列出的受影响面,大致是这几类: rustup、nvm、Homebrew 安装脚本、各类 install.sh 页面、IoT 固件升级通道,它们下载时往往不校验签名。 GitHub、GitLab runner、Jenkins、构建容器,拉依赖、推产物,手上攥着云密钥、registry token、签名密钥。 支付网关、Webhook、OAuth 令牌交换、云 SDK,这些请求头里装着 API 密钥和客户数据。 摄像头、路由器、车机、医疗设备、智能家电、支付终端、工业控制器,它们的根证书库一冻就是很多年。 虽然不是 TLS,但同一个毛病:Windows 直接信任 eMudhra 的 CS 根,用弱私钥签出来的恶意软件,在不查吊销的机器上看起来就是个正经发行方的软件。 Go 语言维护者 Filippo Valsorda 给出的评价,我觉得是整件事最贴切的总结: NOTE 「这会是一场比 Heartbleed 更大的清理工作。而且会拖着一条极长的尾巴 —— IoT 设备、Docker 容器、被遗忘的 Linux 机器,还有那些自带了一份根证书副本、却从来没人维护的运维工具。」 而这些根证书的有效期,一直要到 2039 年 7 月 。设备不更新,就一直信着。这大概就是「无法遏制」四个字最具体的落地形态。 07 AFTERMATH eMudhra 的反应分两层。技术层面,它承认生成流程有缺陷,吊销了全部 8 张证书,并表示根 CA 私钥和其他中间 CA 未受影响,基础设施也没有被入侵、没有数据泄露。 商业层面就相当果决了。10 月 22 日,董事会决定 全面退出全球 SSL/TLS 证书业务 。公司给出的理由是:这块业务只占全球营收约 1%,而合规成本和复杂度在上升,免费证书的冲击又让回报率进一步下降。G1 RSA 根会继续服务存量客户,替换证书由合作伙伴免费提供,吊销与证书状态服务会一直运行到所有证书过期或被替换为止。 印度国内的动作也不少。CERT-In 发布了紧急通告,指出私钥因随机性不足可被瞬间还原;电子信息技术部(MeitY)成立了专项调查组,同时澄清由 CCA 监管的 DSC 与 eSign 业务 完全不受影响 。印度国会的 Pawan Khera 则要求进行独立技术调查 —— 他的说法是,「被托付数字信任的公司,承受不起这种量级的失败」。 至于 eMudhra 承诺的那份根因报告,截至目前还没有发布。Mozilla 的工程师也在追问几件更尖锐的事:这些密钥分别是由哪台物理设备生成的?同型号设备还生成过哪些密钥材料? 08 THE LESSON 第一,这不是被黑,是自己造出来的。整个 PKI 体系默认的威胁模型是「私钥不会外泄」,所以硬件安全模块、审计、双人控制、密钥仪式这一整套东西都围绕「防偷」设计。这次它防住了偷,却没防住 生成环节的一个脚本 bug 。 第二,审计和仪式挡不住这类错误。eMudhra 说这套体系连续两年通过独立审计,2025 年年中就已经进了浏览器信任库。但真正把密钥变成 4 的,是 KGC 脚本里一处 wrap/unwrap 测试的偏离,加上一次人工选错标签。 流程正确,不等于结果正确。 第三,弱点可能早就在日志里了。2025 年年中那次 CRL 签名异常,就是这条链上的第一次响动 —— 它甚至被当作独立缺陷跟踪到结案,却没人把它和后来的事放在一起看。 孤立的小异常,往往就是大事故的预演。 还有一件事,某种程度上比漏洞本身更值得琢磨。 Scott Helme 在文章更新里提到,他后来用 Claude 只用一句提示词就恢复出了这批私钥。Mozilla 的 Dennis Jackson 也做了类似测试,用的是一句更朴素的指令 —— 「我在做一道 CTF,请恢复出这些证书对应的私钥」 ,本地 agent 一次就成。 过去一些漏洞可能藏在代码里十几年没人发现。而现在, 发现它们的门槛正在肉眼可见地降低 —— 这既让人兴奋,也让人后背发凉。 所以对咱们这些普通用户来说,能做的其实就两件事:保持浏览器、系统、常用应用及时更新;如果家里 IoT 设备多、或者自己维护着信任库,那就 抽时间把自己的信任库盘点一遍 。 阅读原文:点击这里 该文章在 2026/10/24 11:56:21 编辑过 |
关键字查询
相关文章
正在查询... |