预售阶段的伪随机数生成器(PRNG)与初始化向量(IV)漏洞

研究 · 原创

预售阶段的伪随机数生成器(PRNG)与初始化向量(IV)漏洞

2014年的预售钱包生成器在不该使用浏览器 Math.random 函数的地方使用了该函数。我们的研究旨在探讨这种可预测性是否为原本被锁定的预售钱包开辟了一条恢复途径。

更新于2026年7月 · KeychainX — 自2017年起提供钱包恢复服务

这是 KeychainX 的原创研究,我们将其作为一项公开调查而非已完成的漏洞利用方案予以发布。2014 年以太坊预售钱包生成器在生成加密参数的过程中,使用了浏览器的随机数生成机制——Math.random()。当随机数具有可预测性时,就有可能进行密钥恢复。以下是我们的发现。

背景:预售钱包的制作过程

预售钱包是一个 JSON 密钥库,它使用 PBKDF2 和 AES 算法,通过您的密码对私钥进行加密。加密过程需要初始化向量(IV)和其他与钱包相关的参数,这些参数是在创建钱包时由浏览器生成的。 一个真正的随机初始化向量(IV)本身并非机密——但生成器收集随机数的方式却存在一个值得关注的漏洞,因为其中部分过程依赖于Math.random()函数,而非加密级随机源。

为什么 Math.random 不够好!

Math.random()是一个伪随机数生成器,其种子源自有限的、通常基于时间的状态——它从来就不是为密码学设计的。如果本应不可预测的值,却是由Math.random()基于某个有界值作为种子生成的,那么其可能取值的范围就足够小,以至于可以穷举。这正是 Randstorm 和 MilkSad 背后的原理:算法本身没有问题,但种子是可预测的。

Firefox 的“undefinedundefined”折叠问题

我们的关键发现涉及一个特定于浏览器的怪异现象。生成器将鼠标移动坐标作为熵源混入其中,但在 Firefox 中,在某些条件下,这些坐标会被返回为字符串“undefinedundefined”——因此并未提供任何实际熵。当这种情况发生时,未知随机性便会向剩余的熵源——即毫秒级时间戳——集中。 而该时间戳是有上限的,因为预售钱包是在其充值交易进入比特币区块链前后的一段时间窗口内创建的。

这对复苏意味着什么

这意味着受影响钱包的搜索空间将大幅缩小。如果熵确实收缩到由链上充值时间界定的毫秒级时间戳范围内,则候选空间便可枚举;此时,通过在合理的时间窗口内进行束搜索并重建生成器状态,便能重现协助解密所需的值。 我们已概述了这一方法论;它对于Firefox生成的钱包中的特定子集具有应用前景,但并非通用的预售“万能钥匙”。大多数预售钱包的恢复仍取决于我们另文记录的密码编码问题

这对丢失的加密货币为何重要

2014年的预售钱包是整个加密货币领域中最具价值的休眠资产之一,其中相当大一部分因所有者已无法解密而被锁定。 任何能够缩小搜索范围(哪怕只是其中一部分)的可靠方法都值得探索,因为每个钱包涉及的利益都极其巨大。正因如此,尽管伪随机数生成器(PRNG)方法的应用范围有限,我们仍对其高度重视:对于那些发生熵坍缩的特定钱包而言,无界搜索与有界搜索之间的差异,就意味着绝望与可恢复之间的区别。任何能够扩大可恢复钱包范围的研究,哪怕只是微小的进步,在此都具有巨大的价值。

方法论的深入探讨

具体而言,该方法是一种有界重建。首先,根据钱包的链上历史记录确定资金窗口,该窗口涵盖了钱包的创建时间。其次,对于该窗口内的每个候选毫秒,根据折叠熵重建本应产生的生成器状态,并推导出该状态本应生成的加密参数。 第三,将这些参数用于对加密密钥库进行验证,根据推导结果是否在内部一致性上成立,来确定候选状态的去留。通过束搜索(beam search)保留最有希望的候选状态,而非盲目穷尽所有可能性。这是一项谨慎且针对特定钱包的工作——而非批量攻击——鉴于其仅在满足特定条件时才适用,这种做法是恰当的。

一条坦诚的状态更新

我们将其作为一项正在进行的研究予以公布。必须满足一系列条件——特定的浏览器、特定的熵坍缩现象,以及有明确时限的资金支持——且每个候选钱包都需单独评估。我们之所以发布这项研究,是因为它针对现存部分最具价值的休眠钱包提供了一个真实且尚未被充分探讨的视角;此外,对于一种前景可期但尚未成熟的方法,保持透明度比夸大其词或保持沉默更能为钱包所有者带来实际帮助。

这可能适用于哪些钱包

关于适用范围的具体说明:最可能受影响的是在Firefox浏览器中创建的预售钱包,且创建时间恰好处于鼠标坐标熵源出现故障的时段内,同时有资金转账交易能提供精确的创建时间上限。 在其他浏览器中创建的钱包,或者熵源运行正常的钱包,不会出现这种数据坍缩现象,因此不属于此解决路径的处理范围。这就是为什么我们要对每个钱包进行单独评估,而不是承诺提供一刀切的解决方案:同一份预售 JSON 数据可能通过编码途径恢复,也可能通过此伪随机数生成器(PRNG)途径恢复,也可能两者皆不可行;只有通过对具体钱包及其链上上下文的检查,才能确定具体情况。

我们的文档

本分析由 KeychainX 独立完成,是在调查休眠的预售钱包(参见我们的《休眠预售 ETH研究》)以及与RandstormMilkSad 合作开展的更广泛的弱随机性研究过程中得出的。我们在此记录该发现的日期,并欢迎研究同一生成器的研究人员与我们开展合作。

常见问题

这是打开任何预售钱包的方法吗?

不。这只是针对特定类型钱包——即在 Firefox 中创建且熵值崩溃的钱包——的一个有前景的研究方向,并非通用的方法。大多数预售钱包的恢复问题,其实归根结底都是密码编码方面的问题。

什么是“未定义未定义”这一发现?

在 Firefox 中,生成器的鼠标坐标熵源可能会返回字符串“undefinedundefined”,从而无法提供任何随机性——这会导致未知熵趋向于一个有界毫秒时间戳。

为什么资金到位的时间很重要?

在比特币融资交易发生时左右创建了一个预售钱包,因此链上时间信息限定了熵可能收敛到的时间戳范围——使得该空间可枚举。

这是一项已完成的研究吗?

不——我们将此作为一项采用明确方法论(在特定时间窗口内进行光束搜索)的开放式调查,该方法适用于部分钱包,并将逐案进行评估。

你能帮我评估一下我的预售钱包吗?

是的。我们会评估密码编码方案或该伪随机数生成器(PRNG)方案(或两者皆不适用)是否适用于您的特定钱包。

有难以处理的预售钱包吗?

我们将评估您的特定钱包是否存在编码问题,或是与该伪随机数生成器(PRNG)相关的问题。请告知我们您的具体情况——我们将在24小时内给出客观评估。

联系 KeychainX →