目前,在以太坊上有3.45亿笔交易,涉及4700万对密钥对。新生成的密钥与现存密钥重复的概率大约是2的256次方分之一,这几乎是不可能发生的。
在本文中,我们研究了即使面对这种统计上的小概率事件,ISE发现了732个私匙及其对应的公钥,这些公钥向以太坊提交了49,060笔交易。此外,还确定了13319个以太坊被交易到无效的目标地址,或者来自弱密钥的钱包,这些ETH在以太坊市场鼎盛时期的总价值为18,899,969美元。
在这个过程中,我们发现来自这些弱密钥地址的资金正在被窃取,并被发送到一个目标地址,该目标地址属于一个正在运作的个人或团体,其目的是破解或收集私钥并获得这些资金。2018年1月13日,这名“区块链强盗”持有37926 ETH,价值54343407美元。
仅仅覆盖1%的密钥空间,即使我们使用的计算资源允许我们每秒生成100万亿的密钥,也需要大约几年的时间。
然而,我们没有尝试暴力搜索随机私钥,而是设计了一些方法来发现可能使用错误代码、错误随机数生成器或这两者的结合生成的密钥。以下部分概述了如何生成以太坊地址,以及破解没有使用最佳方式生成的私钥。
该哈希值被截断到较低的160位,以生成以太坊地址。以太坊地址不能逆转为公钥,也不能以任何方式使用以太坊地址生成它的底层私钥。
给定随机生成的私钥,其有效范围为1到secp256k1曲线所定义的最大值,0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140,可以通过取公钥的keccack256哈希函数的较低(最右)160位来计算以太坊地址,
定义为:
图1演示了从随机生成的256位私钥到生成以太坊地址的工作流程。
图1:从私钥到生成以太坊地址的示例流程。
知道了这个算法,我们的研究目标是找到那些没有用合理正确算法生成的以太坊地址,或者从非随机私钥不正确生成的地址。
为了便于使用,一些在线服务通过web接口封装底层数据。Etherscan就是这样一个工具,它可以从上面的例子中查询公开的以太坊地址:
l A99FDD90FF61DD08CF049155D18E086F7806641B
您可以到https://etherscan.io/address/A99FDD90FF61DD08CF049155D18E086F7806641B
查询,毫无疑问,这个地址有0笔交易。
图2:Etherscan.io查询A99FDD90FF61DD08CF049155D18E086F7806641B 由于以太坊上记录了近5000万个公开的以太坊地址,由于一些因素,我们可能会遇到弱或者说缺乏随机性的密钥。一个明显的例子是密钥截断。
也就是说,生成一个随机的256位私钥,但是由于编码/编译器/框架或其他未知错误,只使用了一小部分的功能。
例如,一个256位私钥,其值为:
l 0x47579DA2BEA463533DBFAD6FCF8E90876C2FE9760DC1162ACC4059EE37BDDB5C
如果截短到32位,会得到如下密钥:
l 0x0000000000000000000000000000000000000000000000000000000037BDDB5C
在实验中,我们选择了一个私钥为1,仅仅是因为它可能是secp256k1的私钥的下界,并且它也位于32位截断密钥的1到232-1范围内。
我们使用私钥0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
推导出以太坊地址0x7e5f4552091a69125d5dfcb7b8c2659029395bdf
如前所述,回想一下两个以太坊用户生成相同私钥的无穷小的概率。假设至少有一个用户随机生成它们。则该地址不应该与另一个以太坊用户随机生成的密钥发生巧合。
这与是否从下界、上界、或使用π位密钥、以及随机等数字的密钥来探索密钥空间是无关紧要的。
相反,使用Etherscan.io查询来自0x01私钥的上述地址上的交易数据,我们将看到以下证据,表明与我们有意生成的密钥发生了冲突。(比如:这个密钥已经在使用中)
图3:Etherscan.io查询7e5f4552091a69125d5dfcb7b8c2659029395bdf
ISE显示,从0x01的私钥派生的以太坊地址上有592笔交易,而该地址上当前没有ETH。如果随机选择一个私钥,那么其他人生成相同密钥的几率大约是2的256次方分之一,这实际上来说是0%的几率。
由于随机生成私钥为0x01所发生的概率大约为零,所以我们必须假设这个值是故意选择的,或者是由于错误。下面的部分详细介绍了我们的研究,以了解和研究在以太坊中弱密钥的生成到底有多普遍。
- 代码逻辑错误
- 类型混淆
- 熵的错误
- 随机策略错误
- 处理异常
- 内存引用错误
- 内存泄露
- 种子重用
- 对恶意软件的妥协
因此,转而关注可实现的目标:枚举将出现在256位私钥的更小的32位子集中的密钥。这相当于4,294,967,295个私钥,需要为其计算相应的公开的以太坊地址并查询区块链。
取而代之,在内存中生成一个所有公开的以太坊地址的的哈希映射,并在这个内存中查询每个枚举密钥的数据结构。
在一个中档笔记本上,其性能约为每个CPU每核每秒约生成15,000个密钥及其查询,瓶颈是ECDSA私钥到公钥的生成。
将重点放在256位密钥空间中的8个32位“子区域”上,在这些子区域中,可能会观察到正在使用的以太坊地址是由弱私钥导出的。
预期密文空间的下32位部分最有可能包含弱密钥。为了考虑到字节顺序,还扫描了较高的32位部分,为了彻底起见,使用一个可能产生密钥的32位窗口测试了256位密钥空间的每个不同部分。
为了说明扫描的区域,下面的图4描述了为枚举标识的每个区域。在枚举每个区域(A到H)的32位密钥空间时,将256位密钥的其余224位设置为0x00。
图4:256位密钥空间由H到A部分表示。
这给了8个可能的区域,每个区域的组合数为2的32次方减一 (大约 43亿)。将区域定义转换为明确的私钥范围,扫描并测试了以太坊区块链上交易活动的这些密钥范围:
组A:
0000000000000000000000000000000000000000000000000000000000000001 到
00000000000000000000000000000000000000000000000000000000FFFFFFFF
组B:
0000000000000000000000000000000000000000000000000000000100000000 到
000000000000000000000000000000000000000000000000FFFFFFFF00000000
组 C:
0000000000000000000000000000000000000000000000010000000000000000 到0000000000000000000000000000000000000000FFFFFFFF0000000000000000
组 D:
0000000000000000000000000000000000000001000000000000000000000000 到
00000000000000000000000000000000FFFFFFFF000000000000000000000000
组 E:
0000000000000000000000000000000100000000000000000000000000000000 到000000000000000000000000FFFFFFFF00000000000000000000000000000000
组 F:
0000000000000000000000010000000000000000000000000000000000000000 到0000000000000000FFFFFFFF0000000000000000000000000000000000000000
组 G:
0000000000000001000000000000000000000000000000000000000000000000到00000000FFFFFFFF000000000000000000000000000000000000000000000000
组 H:
0000000100000000000000000000000000000000000000000000000000000000 到FFFFFFFF00000000000000000000000000000000000000000000000000000000
上面的密文空间范围虽然构成256位密文空间的无穷小部分,但由于错误或其他因素影响了256位密文的随机性,因此私钥可能存在于这些区域。
来源:格密链