
科普:真随机数和伪随机数「附Tron豹子号生成代码」
科普
比特币用户很喜欢讨论“非对称加密”、“椭圆曲线”、“量子计算机”这类高深莫测的话题,然后再以一种非常莫名其妙的方式把币弄丢,比如说:“随机”。
历史上多起各品牌的钱包用户丢币事件,都是因为随机函数存在问题。
随机很重要,对于比特币这种密码学电子货币来说,尤其重要。可惜社区内对于随机的讨论并不多,导致很多人缺乏正确的认识,因此,我们今天就和大家聊聊随机。
说到随机,有两个必须要搞清楚的概念:“真随机数生成器”(TRNG)和伪随机数生成器(PRNG)。
大部分计算机程序和语言中的随机函数,都是伪随机数生成器,它们都是由确定的算法,通过一个“种子”(比如“时间”),来产生“看起来随机”的结果。
毫无疑问,任何人只要知道算法和种子,或者之前已经产生了的随机数,都可能获得接下来随机数序列的信息。因为它们的可预测性,在密码学上并不安全,所以我们称其为“伪随机”。这种随机数,用来让游戏里的小人跑跑路没多大问题,如果用来生成比特币私钥,那可就太不安全了。
再说说真随机数生成器,中文维基中,将“硬件随机数生成器”(HRNG)等同于真随机数生成器,这其实并不十分准确,严格意义上的真随机可能仅存在于量子力学之中,我们当前所想要的(或者所能要的),并不是这种随机。
我们其实想要一种不可预测的、统计意义上的、密码学安全的随机数,只要能做到这一点的随机数生成器,都可以称其为真随机数生成器。这种真随机,并不一定非得是特殊设计的硬件,Linux操作系统内核中的随机数生成器(/dev/random
),维护了一个熵池(搜集硬件噪声,如:键盘、鼠标操作、网络信号强度变化等),使得它能够提供最大可能的随机数据熵,因此同样是高品质的真随机数生成器。
不过/dev/random
是阻塞的,也就是说,如果熵池空了,对于/dev/random
的读操作将被挂起,直到收集到足够的环境噪声为止。
因此,在开发程序时,我们应使用/dev/urandom
,作为/dev/random
的一个副本,它不会阻塞,但其输出的熵可能会小于/dev/random
。
好了,在说了这么多之后,在我们开发比特币应用时,应该使用何种随机数生成器来生成私钥呢?
答案很简单:urandom
。永远只用urandom
。
不要使用任何第三方的随机数解决方案,哪怕是一些高级的安全库,所提供的声称“非常安全”的随机函数。因为它们都是用户态的密码学随机数生成器,而urandom是内核态的随机数生成器,内核有权访问裸设备的熵,内核可以确保,不在应用程序间,共享相同的状态。
历史上,无数次随机数失败案例,大多出现在用户态的随机数生成器,而且,用户态的随机数生成器几乎总是要依赖于,内核态的随机数生成器(如果不依赖,那风险则更大),除了没准儿能简化您的某些开发工作,丝毫看不出任何额外的好处,反而增加了因引入第三方代码,所可能导致的潜在安全风险。
因此,开发者在需要密码学安全的随机数时,应使用urandom
。
代码
1 | import secrets # 导入secrets模块,用于生成安全随机数 |
执行
新建虚拟环境「可选」
python3 -m venv myenv
进入虚拟环境
source myenv/bin/activate
安装依赖
pip install colorama ecdsa base58 pycryptodome
运行
python xx.py -h
执行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15$ python ./XXX.py -h
usage: XXX.py [-h] [-q] [-b BITS] [-n NAME]
生成Tron钱包豹子尾号地址
optional arguments:
-h, --help 显示此帮助信息并退出程序,使用:-h or --help
-q, --quiet 是否将生成的公私钥输出到控制台
-b BITS, --bits BITS 钱包地址相同后缀位数,使用:-b number or --bits number
-n NAME, --name NAME 输出文件的名称,使用:-n name or --name name
$ python ./XXX.py -b 3
Please Wait...
1 | 9e533918217dea1c77e3aa32c509f5454ec2b895668f9aa2700e713b19fd5720 | TFotRzQVXspDtr1ebMZmL2LJFDkzU2Keee
2 | 1fe5f63d4dad586e6e78259b792752fa68ce81e00b555a9bc7b88f85f78cf0a1 | TAzGmUqePT3VYo1wBHYHkmVyCa5oXGCSSS上面代码,
os.urandom(32)
是一种非常安全的随机数生成方法,特别适合用于密码学用途。它通过操作系统提供的加密随机数生成器生成随机字节,满足高安全性的需求,os.urandom
调用的是操作系统底层的加密随机数生成器。- 在 Linux 、Mac上,它会使用
/dev/urandom
。 - 在 Windows 上,它会调用
CryptGenRandom
或类似的 API。
这些随机数生成器的设计目标是提供密码学安全级别的随机性,因此
os.urandom(32)
是足够安全的,特别是用于生成私钥。- 在 Linux 、Mac上,它会使用
替代方案
如果需要更高的控制或对随机性来源有更严格的要求,可以使用以下方法,但它们通常不必要:
Python 3.6+ 中的
secrets
模块:1
2import secrets
raw = secrets.token_bytes(32)secrets
是专为密码学设计的模块,与os.urandom
底层依赖相同,但提供了更高级的接口。
- 感谢您的赞赏