有人正在清空那些本不应被触及的比特币钱包。这些币存放在加拿大制造商Coinkite旗下的冷钱包Coldcard设备上——一款永不联网的硬件钱包。没有钓鱼链接,没有恶意软件,没有被盗的笔记本电脑。攻击者只是直接算出了私钥。
Galaxy Research报告称,已追踪到超过1,596 BTC被盗,涉及三次确认的攻击波,还有第四次疑似攻击波,可能使总损失达到约2,055 BTC——按当前价格计算约1.3亿美元。其中一次攻击在41分钟内转移了7000万美元。Coinkite表示至少有15个不同的攻击者参与其中。该公司在8月1日发布了一份技术背景说明,解释了问题所在。这是一份异常坦诚的文件,简而言之:八年来,钱包一直在使用“有偏的骰子”,却无人察觉。
零仍然算“定义”
2021年,Coinkite将Coldcard的加密算法迁移到libsecp256k1(比特币核心使用的同一库)。这是个合理的决定,但集成过程出了问题。迁移悄悄地将种子生成路径从Coldcard自己的硬件随机数生成器切换到了MicroPython的软件备用方案——一个名为Yasmarang的小型算法,原本是为完全没有随机数芯片的设备准备的。Coldcard有随机数芯片,只是不再被调用了。
原因小得令人难以置信。一个构建守卫使用了#ifndef,它检查某个设置是否存在,而不是检查该设置是否被启用。Coinkite将该设置定义为0,意为“关闭”。但因为零仍然算作“已定义”,安全检查通过了,构建完成。两个版本的函数签名完全相同,因此看起来一切正常。Coinkite写道:“Coldcard的大部分随机性来自一个伪随机数生成器(PRNG),我甚至不知道它实际存在于源代码中。”伪随机数生成器是一种软件算法,它产生的数字看起来随机,但遵循固定的起始值配方。输入相同的起始值,就会得到相同的输出。每次都是。
在运行固件4.0.1至4.1.9的Mk2和Mk3设备上,起始值来自芯片的序列号和时钟。Coinkite估计由此产生的搜索空间约为40位。较新型号混入了一些安全元件熵,提升至约72位。两者都未达到128位的目标。这个差距比看起来要严重得多。位是指数级的。128位搜索空间包含的组合数量超过可观测宇宙中的原子总数,没有人能搜索完。40位大约是一万亿——一台不错的笔记本电脑就能轻松处理。每减少一位,工作量就减半。Block的工程团队发布了他们的分析,认为新设备有效安全元件搜索空间为2^32个候选值,平均约需2^31次尝试。他们对旧款主板的评估更直接:对于已知的设备ID、定时器状态和调用历史,钱包生成是确定性的。而确定性意味着可预测,这与密码学必需的随机性截然相反。不是“弱”,而是“可预测”。
Coinkite怀疑攻击者是通过机器发现的。“我们必须假设有人使用了AI来审查我们之前版本的固件,并偶然发现了这个问题,”该公司写道,并补充说他们最近用最好的AI模型扫描了相同的代码,但一无所获。“攻击者和防御者拥有相同的AI工具,但今天它没有帮助我们,只帮助了坏人。”针对所有受影响型号的修复固件已发布。它无法修复现有的种子;这些钱包必须重新生成,并转移资金。Decrypt已报道了这种空气隔离存储方式在漏洞利用后的变化,并追踪损失超过1.14亿美元。
熵到底是什么
熵衡量的是攻击者不知道的信息量。换句话说,它基本上是不确定性,以位为单位计量。一位相当于一次抛硬币:两种结果,猜测者有一半的概率猜对。十位对应1024种结果。每增加一位,猜测者的工作量翻倍。比特币钱包就是一个被保密的极大数字。人们向地址发送币的地址是通过数学方法从该数字推导出来的,而且推导是单向的——你可以从密钥到地址,但永远无法反向。因此,每个钱包的安全性取决于一个问题:攻击者需要尝试多少个数?如果数字是以128位熵生成的,答案是“超出物理学允许的范围”。如果是以40位生成的,答案是“给我点时间”。这与量子计算威胁值得争论的原因相同——量子机器会攻击连接密钥和地址的数学算法。而Coldcard漏洞从未需要用到这一点。它让密钥在数学介入之前就变得可猜测。
这里词汇容易混淆。伪随机数生成器产生的输出能通过随机性统计测试——基本上没有任何电子表格会标记异常。但该输出完全由其种子值决定。它看起来随机,但实际不是。统计随机性和密码学不可预测性是两种不同的性质,而Coldcard的输出可以通过第一种测试,但完全无法通过第二种。真正的随机性必须来自物理噪声:电路中的电抖动、热波动、放射性衰变。这就是Coldcard上的硬件芯片的作用。而这个芯片被构建标志断开了连接。
然后Luke Dashjr提到了骰子
当用户慌忙重新生成种子时,许多人转向了明显的低技术解决方案。Coldcard允许你掷物理骰子并将结果输入作为熵。Coinkite自己的指南认为,使用至少50次独立、私密的掷骰子生成的种子不会受到该漏洞的影响。听起来可能有点蠢,但该公司实际上销售一袋“100个可爱小巧的骰子”来让这个过程更轻松。7月31日,比特币核心开发者Luke Dashjr发布警告:“相当多的人建议/使用骰子来缓解Coldcard漏洞。请注意,普通骰子并非设计为密码学安全。如果你要这样做,你可能应该购买精密赌场骰子。即便如此,也还需要另一个熵源。”比特币推特上对此反应激烈。“哈哈,现在连掷骰子都不行了,”一位用户写道。“自我托管完了……”另一个问是否应该雇一个帕金森病患者来掷骰子。(这不礼貌。)
可能最有用的回复来自数学计算。开发者Justin Sharp计算了一个坏骰子到底会损失多少熵:“过度担心了。完美的d6每个掷骰提供2.585位熵。一个明显有偏的骰子,例如某一面出现概率20%而不是16.7%,仍然提供约2.55位。在99次掷骰中,这相当于约256位和约252位熵的差异。”256位中损失了4位。这就是一个明显不公平的骰子的全部代价。Dashjr说廉价骰子存在可测量的偏差并没有错——注塑成型的凹点会从每个面移除不同量的塑料,这正是赌场使用平面填充精密骰子的原因。他在物理学上是对的,但在利害关系上错了。从256位中损失4位还剩252位。而Coldcard漏洞让用户只剩下40位。不过,他的建议中隐藏着一个更尖锐的论点,而且这并非关于制造公差。它关乎不要信任任何单一来源。Coldcard的失败并非其熵轻微偏差——而是一个组件悄悄停止贡献,却没有任何东西捕获到它。
该怎么办
如果你在受影响的Coldcard上生成了种子,且没有使用骰子(真的)或强BIP-39密码短语,那么该种子已被攻破。更新固件,生成新种子,验证指纹,发送测试交易,然后转移所有资产。Coinkite的公告按型号逐一说明了步骤。导出的种子会携带缺陷——将坏种子转移到其他钱包应用并不能解决问题。对于其他人来说,教训不在于硬件钱包被破解或骰子是个陷阱。而在于“随机”是一种声明,这种声明需要被验证。Coldcard的源代码一直是公开的。预期的硬件随机数生成器就在二进制文件中。审查者确认了它的存在,但从未确认种子生成器实际调用了它。八年的审计看了正确的代码,但没有人检查它是否真的运行了。
