黄金加密学
菜单

Coldcard 种子随机性漏洞解析:固件修复为何不能保护旧私钥

原文发布于 2026 年 8 月 11 日 19:00(UTC+8),作者 Johan、Lisa,编辑 77。以下事件规模、技术复现及资金流向均据慢雾原文整理;链上余额与调查进展对应原文发布时点,不代表实时状态。

事件范围:攻击针对种子生成,而非远程控制设备

据慢雾报道,2026 年 7 月 30 日,一批比特币地址出现集中转出:41 分钟内,1,196 个单签地址被清空,涉及约 1,082 BTC。截至当年 8 月上旬,原文称已确认损失至少 1,719 BTC,约合 1.11 亿美元,涉及超过 5,200 个地址,攻击分为三到四波。

原文描述的受影响钱包,多数长期处于冷存储状态;其私钥由 Coldcard 硬件钱包生成,用户未额外加入骰子熵,也未启用 BIP-39 passphrase。

慢雾将攻击归因于种子生成过程中的随机性缺陷,而非远程入侵或供应链投毒:攻击者无需接触设备,而是离线枚举可能的随机状态,重新计算种子、私钥与地址。

原文列出的影响范围为:

设备与固件 原文所述有效熵
Mk2、Mk3,固件 4.0.1 至 4.1.9 约 40 bit
Mk4、Mk5、Q 的特定固件版本 约 72 bit

原文没有列出后三款设备全部受影响版本的清单,其详细代码复现以 Mk3 固件 4.1.9 为例。

随机数接口背后的信任边界

按原文分析,Coldcard 原本应使用 STM32L475 芯片的硬件真随机数发生器(TRNG)生成种子,但构建配置与底层接口的组合,使一条被上层当作硬件随机源的调用路径,实际返回了软件伪随机数。

硬件随机数支持关闭后,接口静默降级

Coldcard 在 mpconfigboard.h 中将 MicroPython 的 MICROPY_HW_ENABLE_RNG 设为 0。原文解释,团队已有自己的 ckcc.rng_bytes 硬件随机数封装,因此关闭了 MicroPython 自带支持。

问题在于,libngu 的 my_random_bytes() 通过 CHIP_TRNG_32() 调用的却是 MicroPython STM32 移植层的 rng_get()。该函数在上述宏为零时,不再读取硬件 RNG 寄存器,而是进入软件兜底分支,返回 Yasmarang 伪随机数发生器的输出。

于是,上层代码所信任的“硬件随机数”,实际已跨过了一个未被察觉的接口边界。

两条伪随机序列不能补足熵

据慢雾复现,libngu 还会将上述输出与自身的一条 Yasmarang 序列异或。但这条序列的初始参数是公开的编译期常量,包括 pad = 0x0a8ce26f、n = 69、d = 233,所有设备相同,能够预先计算。

真正需要枚举的变量,主要来自另一条 Yasmarang 实例的初始化:

  • pad = UID ^ SysTick;
  • n = RTC_TR;
  • d = RTC_SSR;
  • dat = 0。

原文指出,固件只读取芯片 96 bit 唯一标识中的低 32 位,其中包含晶圆坐标,取值范围受到限制;SysTick 的候选范围为 0 至 79,999。RTC 寄存器构成额外枚举维度,但慢雾称,其确认的全部链上命中向量中,这两项均为零。

结合用户按键带来的状态变化,慢雾估计该 Mk3 路径的实际搜索空间约为 36 至 37 bit,并认为这与其引述的 Coinkite“约 40 bit”表述相符。输出长度足够长,并不意味着其不可预测性同样充足。

为何按键过程也能被建模

原文分析显示,设备首次启动时的条款确认、PIN 输入和菜单导航,会消耗伪随机序列。按键扫描调用洗牌函数,改变后续生成种子时所处的随机状态。

慢雾针对 Mk3 4.1.9 区分了三类流程:

  1. 零售设备首次启动:包括条款确认、设置存储槽洗牌、PIN 输入和菜单操作,随后生成 32 字节随机数据。
  2. 刷机或清空后的首次启动:空白 NVRAM 初始化还会增加洗牌和数据清空所需的状态推进。
  3. 纸钱包生成:进入 Paper Wallets 菜单后,生成的 32 字节随机数据直接用于私钥,不经过 BIP-39 助记词流程。

对于助记词钱包,原文描述的路径是:随机字节先经一次 SHA-256,再转换为 24 个英文 BIP-39 单词,之后通过 PBKDF2-HMAC-SHA512 和 BIP-32 派生密钥与地址。

这些后续运算都是确定性的。因此,一旦初始随机状态及其消耗过程被重建,增加哈希或密钥派生步骤并不能补回种子生成时已经缺失的熵。

原文还给出了 GPU 搜索耗时估算,但这些数字属于其特定候选空间和实现条件下的描述,不宜视为所有设备型号均已获得同等复现验证。

资金追踪:区分已转出资金与仍留在 Vault 的资金

MistTrack 部分结合了 Galaxy Research 已公开披露的数据,以及慢雾跟进事件时收集的求助资料。原文明确说明,分析仅覆盖当时可观测的链上数据,后续识别可能改变统计范围。

其中几项需要分别理解:

  • 第一波和第二波涉及多个归集地址及后续转账,原文分别列出了收入和余额;这些余额是当时的观察值。
  • 第三波涉及约 293 个 P2WSH Vault 地址,合计约 207.73 BTC。原文称这些 Vault 中的资金当时均未转出,不能将其直接表述为已经被盗转走的金额。
  • 第四波中,一个地址累计收入 64.9037 BTC,原文称资金已转入 Wasabi Wallet。
  • 另一公开相关地址累计收入 17.6709 BTC。原文列出的部分去向包括:4.4372 BTC 转入另一个比特币地址;6 BTC 经 THORChain 兑换为 204.7 ETH,进入以太坊地址 0x41b7529a411eea979a8d468bdebd36b0ad703268。原文称,该以太坊地址随后向 Tornado Cash 转入 200 ETH,观察时余额为 4.7073 ETH。

最后一组数据没有在文字中完整交代 17.6709 BTC 的全部去向,因此不能据此补全未说明的资金路径,也不能将每次归集、兑换或后续转账重复计入损失。

修复固件与旧种子是两件事

据原文,Coinkite 于 7 月 30 日发出警告,次日发布修复固件,并销毁漏洞版本库存、暂停发货。原文列出的升级要求是:

  • Mk2、Mk3:4.2.0 及以上;
  • Mk4、Mk5:5.6.0 及以上;
  • Q:1.5.0Q 及以上。

但固件升级不能追溯性地提高旧种子的随机性。修复随机数生成路径,只能保护此后重新生成的种子,不能让已有弱种子重新变得不可预测。

原文给受影响用户的处置顺序是:先升级到修复版本,再重新生成种子;先做小额转账测试,确认地址无误后迁移全部资金,并保留旧设备以备后续调查。

这起事件在原文中揭示的核心问题,不是冷钱包是否联网,而是私钥生成时究竟依赖了什么随机源,以及上层代码对底层接口的信任是否成立。

阅读原文:Coldcard 1.11 亿美元被盗事件:私钥破解漏洞深度解析

延伸阅读