主页 > 以太坊imtoken > 深入比特币原理(二)——比特币密钥地址生成

深入比特币原理(二)——比特币密钥地址生成

以太坊imtoken 2023-07-26 05:09:03

【摘要】 比特币的安全性是由现代密码学提供的,其中最重要的就是比特币的密钥。我们来看看比特币的密钥生成过程。比特币地址其实是从公钥转换而来的,而公钥其实是从私钥转换而来的,所以其实一切的来源都是随机生成的私钥。

本章开始出现密码学内容,希望大家不要被劝退,加油!

比特币的安全性是由现代密码学提供的,其中最重要的是比特币的密钥。我们来看看比特币的密钥生成过程。

比特币地址其实是从公钥转换而来的,而公钥其实是从私钥转换而来的,所以其实一切的来源都是随机生成的私钥。

步骤1:通过操作系统随机数生成器生成一个随机数,并进行SHA256哈希运算(结果必须在1和n-1之间的任意数,n=1.158 * 107< @7)

这个数字是私钥最原始的内容,所以需要从一个加密安全的随机源中选择一串随机字节来防止暴力破解

比特币的原理

SHA256哈希运算用于方便地生成一个定长的256位数字,用十六进制表示如下:

6954ac6d0402d7239f1cc150da224d0ef08fd1226f245f06fe4d6d68accfce8a

第2步:如果使用压缩公钥比特币的原理,则在私钥结果中添加0x01;如果使用未压缩的公钥,则不要添加 0x01

私钥后缀01 用于告诉钱包私钥对应的公钥和地址是压缩格式还是未压缩格式。

原因是同一个私钥的压缩公钥和未压缩公钥不同,生成的地址也完全不同,也就是说会有两个公钥和两个地址对应到一个私钥。如果没有标识,钱包无法将私钥与公钥和地址一一匹配。

这次使用压缩格式的例子:

6954ac6d0402d7239f1cc150da224d0ef08fd1226f245f06fe4d6d68accfce8a01

比特币的原理

第三步:用base58check对私钥进行编码比特币的原理,即转换为WIF(Wallet Import Format)格式

(<@@1)在私钥前加一个版本前缀,0x80为WIF前缀(详见最后一个版本前缀列表)

806954ac6d0402d7239f1cc150da224d0ef08fd1226f245f06fe4d6d68accfce8a01

(2)Double-经过SHA256运算后,取前四个字节作为校验码拼接在最后,然后进行base58编码得到私钥的最终形式(结果前缀非WIF压缩格式为5,WIF压缩格式结果前缀为K或L)

KzkTe43L5cbSX64txJMcsFvJC6vov7nYaGdYicz5N8Mds4ThN2XM

第四步:使用secp256k1椭圆曲线算法将私钥转换为公钥(Gx,Gy)

椭圆曲线算法是一种基于离散对数的算法问非对称加密方式的数学运算是单向的,所以私钥可以转换成公钥,但是公钥不能转换回私钥将上述结果转换后,得到如下结果(十六进制):

比特币的原理

(0ba1ba3b8d8f7bd4a70828ec0e749dd26ee4cdd18d058c880afa121fad60e5b6,

f2ee1b72d9b9a57706e5de72acc1378f92269086c4964c073593bf92d28c647d)

步数:将形成十六进制数

压缩可以压缩 保存公钥占用的空间(红色占256bits),是目前比特币客户端默认的格式,也兼容未压缩的公钥

未压缩(前缀04,拼接Gx,Gy):

未压缩(前缀04,拼接Gx,Gy):p>

040ba1ba3b8d8f7bd4a70828ec0e749dd26ee4cdd18d058c880afa121fad60e5b6f2ee1b72d9b9a57706e5de72acc1378f92269086c4964c073593bf92d28c647d

比特币的原理

<压缩压缩>为偶数显示02,y为奇数显示03,仅保留Gx,Gy可通过Gx)

030ba1ba3b8d8f7bd4a70828ec0e749dd26ee4cdd18d058c880afa121fad60e5b6

第 6 步:将公钥转换为比特币地址

(1)RIPEMD160(SHA256(public key)) 得到20字节/160位公钥hash,使用两个Hash函数转换的最大优点是如果其中一个函数被破解,安全性是还是有保证的。

(2)Base58check encoding on the public key hash (version prefix + public key hash + SHA256(SHA256(version prefix + public key) key hash的前4个字节))是Base58编码的),这里为P2PKH地址,前缀为0x00,最终比特币地址如下:

17FjrmErg5a39P7UsyYCchpyzSnq9gmMuJ

比特币的原理

每个版本的前缀说明

最后放一段 Python 代码 GenerateKey.py 用于生成私钥和公钥和地址,需要导入比特币模块

python 代码:

import bitcoin
# Generate a random private key
valid_private_key = False
while not valid_private_key:
    private_key = bitcoin.random_key()
    decoded_private_key = bitcoin.decode_privkey(private_key, \'hex\')
    compressed_private_key = private_key + \'01\'
    valid_private_key = 0 < decoded_private_key < bitcoin.N
print("Private Key (hex) is: ", private_key)
print("Private Key (decimal) is: ", decoded_private_key)
print("Private Key Compressed (hex) is: ", compressed_private_key)
# Convert private key to WIF format  bin_to_b58check(encode(priv, 256, 32)+b\'\x01\', 128+int(vbyte))
wif_encoding_private_key = bitcoin.encode_privkey(decoded_private_key, \'wif\')
wif_compressed_private_key = bitcoin.encode_privkey(decoded_private_key, \'wif_compressed\')
print("Private Key(WIF) is: ", wif_encoding_private_key)
print("Private Key(WIF-Compressed) is: ", wif_compressed_private_key)
# Multiply the EC generator point G with the private key to get a public key point
public_key = bitcoin.privkey_to_pubkey(decoded_private_key)
print("Public Key (x,y) coordinates is:", public_key)
# Encode as hex, prefix 04
hex_encoded_public_key = bitcoin.encode_pubkey(public_key,\'hex\')
print("Public Key (hex) is:", hex_encoded_public_key)
# Compress public key, adjust prefix depending on whether y is even or odd
hex_compressed_public_key = bitcoin.encode_pubkey(public_key,\'hex_compressed\')
print("Public Key (hex) is:", hex_compressed_public_key)
# Generate compressed bitcoin address from compressed public key
print("Compressed Bitcoin Address (b58check) is:", bitcoin.pubkey_to_address(hex_compressed_public_key))

结果展示:

@ >