比特币私钥是每个比特币钱包都有的一个数字秘密。这个256位数字可以用几种格式表示: 十六进制- 256位,十六进制是32字节,或0-9或a - f范围内的64个字符,base64字符串,wif键,或助记短语。
举例说明:
e9873d79c6d87dc0fb6a5778633389f4453213303da61f20bd67fc233aa33262
第一个方法
生成32字节整数的最简单方法是使用您所知道的语言中的rng库。以下是python中的一些示例:
bits = random.getrandbits(256)
# 30848827712021293731208415302456569301499384654877289245795786476741155372082
bits_hex = hex(bits)
# 0x4433d156e8c53bf5b50af07aa95a29436f29a94e0ccc5d58df8e57bdc8583c32
private_key = bits_hex[2:]
# 4433d156e8c53bf5b50af07aa95a29436f29a94e0ccc5d58df8e57bdc8583c32
然而,普通的rng库并不是生成密钥的最安全的选择。由于生成的字符串基于一个种子(seed),所以种子表示当前时间。如果你知道时间,可以对它进行几次暴力攻击。
密码学上强大的rng
除了标准的rng方法之外,编程语言还为特定的加密任务提供rng。由于rng是由操作系统直接产生的,因此该方法具有较高的安全性。
这使得rng的繁殖更加困难,因为你无法确定产生的时间或种子。甚至他不需要种子,因为它是由程序本身创建的。
在python中,您可以在secret模块中实现加密强rng。
bits = secrets.randbits(256)
#46518555179467323509970270980993648640987722172281263586388328188640792550961
bits_hex = hex(bits)
# 0x66d891b5ed7f51e5044be6a7ebe4e2eae32b960f5aa0883f7cc0ce4fd6921e31
private_key = bits_hex[2:]
# 66d891b5ed7f51e5044be6a7ebe4e2eae32b960f5aa0883f7cc0ce4fd6921e31
专门的网站
有几个网站可以为您随机生成这些数字。random.org是一个为各种目的随机生成数字的网站。另一个受欢迎的网站isbitaddress.org专门为生成比特币私钥而设计。
因为您无法知道random.org是否保存或记录生成的任何数字,所以它不是一个安全的选项。
然而,bitaddress.org是一个开源网站,这意味着您可以检查它的代码以了解它的功能,还可以下载并在脱机模式下在您的计算机上运行它。
该程序使用鼠标或按键移动来产生熵(热力学函数)。这使得复制您的结果变得非常不可能。
然后,以压缩的wif格式交付私钥,但是我们将使算法返回一个十六进制字符串,稍后生成公钥时将需要该字符串。
bitaddress首先初始化字节数组,试图从计算机中获得尽可能多的熵。它用用户输入填充数组,然后生成私钥。该服务使用256字节的数组来存储熵。这个数组是用循环填充的,所以当数组第一次被填充时,指针重置为零,数组将再次被填充。
在从窗口启动数组之后。它编写一个时间戳来生成额外的4字节熵。它收集诸如屏幕大小、时区、浏览器插件信息、地区等数据,以添加另外6个字节。
然后在初始化之后,程序重复等待用户输入重写初始字节。当光标移动时,将写入光标的位置。当按钮被按下时,被按下按钮的字符代码由程序编写。
使用rng算法生成32字节私钥的累积熵称为arc4。
diy版
您还可以创建自己的bitaddress版本。我们不会收集有关用户计算机和位置的数据。熵将仅由文本生成,因为通过python脚本初始化光标的位置相当困难。
字节数组将使用加密的rng初始化,然后填充时间戳,然后使用用户生成的字符串填充。
在填充第二个种子池之后,库将允许您创建密钥。
初始化连接池
我们从加密的rng中插入几个字节和一个时间戳。__seed_int和__seed_byte是两种方法,它们将帮助将熵插入池数组。我们还将在示例中使用secrets模块。
def __init_pool(self):
for i in range(self.pool_size):
random_byte = secrets.randbits(8)
self.__seed_byte(random_byte)
time_int = int(time.time())
self.__seed_int(time_int)
def __seed_int(self, n):
self.__seed_byte(n)
self.__seed_byte(n 》》 8)
self.__seed_byte(n 》》 16)
self.__seed_byte(n 》》 24)
def __seed_byte(self, n):
self.pool[self.pool_pointer] ^= n & 255
self.pool_pointer += 1
if self.pool_pointer 》= self.pool_size:
self.pool_pointer = 0
在这里,我们插入一个时间戳,然后输入字符串的每个字符。
def seed_input(self, str_input):
time_int = int(time.time())
self.__seed_int(time_int)
for char in str_input:
char_code = ord(char)
self.__seed_byte(char_code)
生成私钥
为了用我们的池生成一个32字节的数字,我们必须使用一个共享对象,它被运行在一个脚本中的任何代码所使用。
为了节省每次生成键时的熵,我们将记住在此停止的状态,并为下一次生成键设置状态。
现在我们只需要确保我们的键在范围(1,curve_order)内,这是ecdsa私钥所必需的。曲线的阶数是secp256k1曲线的阶数。
我们将把密钥转换为十六进制,并删除“0x”部分。
def generate_key(self):
big_int = self.__generate_big_int()
big_int = big_int % (self.curve_order — 1) # key 《 curve order
big_int = big_int + 1 # key 》 0
key = hex(big_int)[2:]
return key
def __generate_big_int(self):
if self.prng_state is none:
seed = int.from_bytes(self.pool, byteorder=’big’, signed=false)
random.seed(seed)
self.prng_state = random.getstate()
random.setstate(self.prng_state)
big_int = random.getrandbits(self.key_bytes * 8)
self.prng_state = random.getstate()
return big_int
为了使用该库,您可以使用以下代码生成私钥:
kg = keygenerator()
kg.seed_input
kg.generate_key()
# 60cf347dbc59d31c1358c8e5cf5e45b822ab85b79cb32a9f3d98184779a9efc2
您将注意到,每次运行代码时,您都会得到不同的结果。
结论
根据安全性和实现的容易程度不同,有许多方法可以帮助您生成私钥。
关于如何利用电容器来降低噪声的方法分享
谁才是下一个华尔街的苹果?外媒直指英伟达
双十一网络电视盒子怎么选?数码编辑曝光热门电视盒子排行榜
力矩马达是什么意思_力矩马达的作用
地磁定位技术简介和基本原理
比特币私钥的生成方法
智慧照明网关TG464地下停车场照明解决方案
三星显示器计划将透明PI基板应用于柔性OLED
有很多车用防盗报警遥控器不好用,为什么?
详细剖析云储能
基于控制器LM3445带三端可控硅调光器的离线式LED驱动器
有关透明导电膜的研究分析
怎样使用Python计算曲线的切点?
一文剖析OLED和AMOLED二极管异同
一文解析充电芯片的动态电源路径管理
基于模型的GAN PA设计基础知识:GAN晶体管S参数、线性稳定性分析与电阻稳定性
数字货币的到来有可能打败微信和支付宝吗
简易双频显示器电源电路图
英特尔7nm工艺战略捍卫摩尔定律
5G+智能电网代表测评:宁波国内首款5G配电房投运