zoukankan      html  css  js  c++  java
  • 深入比特币原理(二)——比特币密钥地址生成

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

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

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

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

    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函数转换最大的好处是如果其中一种函数被破解,仍然能保证安全性。 

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

    各版本前缀说明

    最后放上一段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))

    结果展示:

    作者:Aaron

  • 相关阅读:
    POJ 1795 DNA Laboratory
    CodeForces 303B Rectangle Puzzle II
    HDU 2197 本源串
    HDU 5965 扫雷
    POJ 3099 Go Go Gorelians
    CodeForces 762D Maximum path
    CodeForces 731C Socks
    HDU 1231 最大连续子序列
    HDU 5650 so easy
    大话接口隐私与安全 转载
  • 原文地址:https://www.cnblogs.com/2020-zhy-jzoj/p/13165471.html
Copyright © 2011-2022 走看看