云社区 博客 博客详情
云社区 博客 博客详情

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

Aaron 发表于 2018-02-22 09:48:34 02-22 09:48
Aaron 发表于 2018-02-22 09:48:34 2018/02/22
7
4

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

本章开始出现密码学内容,希望你不要就此被劝退,加油0.gif

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

比特币地址实际上是公钥转换而来,而公钥实际上是由私钥转换得到,所以实际上一切的来源都是一个随机生成的私钥。

1w.png

step 1通过操作系统随机数生成器生成一个随机数,并进行SHA256哈希运算(结果必须是1到n-1之间的任何数字,n=1.158 * 1077)

 该数字即为私钥最原始的内容,所以需要通过密码学安全的随机源中选出一串随机字节,以防暴力破解

 使用SHA256哈希运算是为了方便的产生一个固定长度为256位的数字,使用十六进制表示如下:

6954ac6d0402d7239f1cc150da224d0ef08fd1226f245f06fe4d6d68accfce8a


 step 2如果使用压缩公钥,在私钥的结果后面增加0x01;若使用非压缩公钥,则不追加0x01

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

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

 本次使用压缩格式举例:

6954ac6d0402d7239f1cc150da224d0ef08fd1226f245f06fe4d6d68accfce8a01


 step 3对私钥进行base58check编码,即转换为WIF(Wallet Import Format)格式

(1)在私钥前添加版本前缀,0x80为WIF前缀(详细见最后版本前缀列表)

806954ac6d0402d7239f1cc150da224d0ef08fd1226f245f06fe4d6d68accfce8a01

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

KzkTe43L5cbSX64txJMcsFvJC6vov7nYaGdYicz5N8Mds4ThN2XM


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

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

(0ba1ba3b8d8f7bd4a70828ec0e749dd26ee4cdd18d058c880afa121fad60e5b6,

 f2ee1b72d9b9a57706e5de72acc1378f92269086c4964c073593bf92d28c647d)


 step 5:将公钥合并成为十六进制数

压缩公钥可以大大节省公钥所占空间(减少256bits),是比特币客户端当前的默认格式,并且也兼容非压缩公钥

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

040ba1ba3b8d8f7bd4a70828ec0e749dd26ee4cdd18d058c880afa121fad60e5b6f2ee1b72d9b9a57706e5de72acc1378f92269086c4964c073593bf92d28c647d

压缩(y为偶数前缀02,y为奇数前缀03,仅保留Gx,Gy可通过Gx计算)

030ba1ba3b8d8f7bd4a70828ec0e749dd26ee4cdd18d058c880afa121fad60e5b6


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

(1)RIPEMD160(SHA256(公钥))得出20字节/160 bits公钥哈希,使用两种Hash函数转换最大的好处是如果其中一种函数被破解,仍然能保证安全性。 

2w.png

(2)对公钥哈希进行Base58check编码(版本前缀 + 公钥哈希 + SHA256(SHA256(版本前缀+公钥哈希))前4字节进行Base58编码),此处为P2PKH地址,前缀为0x00,得到最终的比特币地址如下:
17FjrmErg5a39P7UsyYCchpyzSnq9gmMuJ

3w.png

各版本前缀说明

4w.png

最后放上一段Python代码GenerateKey.py,用于生产私钥、公钥与地址,需导入bitcoin模块

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))

结果展示:

5w.png


登录后可下载附件,请登录或者注册

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:huaweicloud.bbs@huawei.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
评论文章 //点赞 收藏 4
点赞
分享文章到微博
分享文章到朋友圈

评论 (7)


萌狐想成精

1楼2018-02-27 15:03:46

guangfu007

2楼2018-04-08 17:44:48
表示没看懂。。。。。。。。。。。

混世小朋友

3楼2018-06-22 17:03:34
为什么会出现压缩公钥和非压缩公钥两种

BBY1楼2020-04-24 10:39:08

因为椭圆体制的公钥是一个坐标点,压缩公钥和非压缩公钥应该是椭圆公钥的自带属性
0/1000

hitning

4楼2018-10-08 16:47:22
希望能把椭圆曲线算法,Gx,Gy的含义再解释清楚些

buffett-monitor

5楼2018-11-22 00:01:33

新手来打卡

Leon Xia

6楼2020-01-22 17:32:53
请问下 bitcoin 这个库在哪里,帮忙传一下,谢谢
0/1000
评论

登录后可评论,请 登录注册

评论

您没有权限执行当前操作

温馨提示

您确认删除评论吗?

确定
取消
温馨提示

您确认删除评论吗?

删除操作无法恢复,请谨慎操作。

确定
取消
温馨提示

您确认删除博客吗?

确定
取消

确认删除

您确认删除博客吗?

确认删除

您确认删除评论吗?

温馨提示

登录超时或用户已下线,请重新登录!!!

确定
取消