首页 文章

使用PHP转换比特币私钥,但错误的SHA256?

提问于
浏览
0

https://en.bitcoin.it/wiki/Wallet_import_format

试着在这里用这个例子在PHP中做这个,但是我在第3步陷入困境 .

我似乎无法获得相同的SHA256哈希 .

我从第2步 800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D 获取扩展密钥

和SHA256它 .

我应该按照步骤3获得 8147786C4D15106333BF278D71DADAF1079EF2D2440A4DDE37D747DED5403592 但我得到 E2E4146A36E9C455CF95A4F259F162C353CD419CC3FD0E69AE36D7D1B6CD2C09

我究竟做错了什么?

2 回答

  • 3

    这是因为您正在散列文字字符串

    "800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D"
    

    这不是需要发生的事情 . 这是一串字节 . 它采用HEX格式,只是为了让查看更容易 . 实际上,这代表二进制字符串 . 这就是你需要哈希的东西 .

    hex2bin是你的朋友 .

    <?php
    $hex = '800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D';
    echo hash('sha256', hex2bin($hex));
    

    演示:https://eval.in/69440

    另一个例子:

    <?php
    $key = '0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D';
    $binKey = hex2bin($key);
    
    $binKey = hex2bin(80).$binKey;
    
    echo hash('sha256', $binKey);
    

    演示:https://eval.in/69443

  • 0

    这是工作的PHP代码示例:

    <?php
    
    //EXAMPLE INPUT: 0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D
    //EXAMPLE OUTPUT: 5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ
    //see https://en.bitcoin.it/wiki/Wallet_import_format for more info
    
    function decodeHex($hex)
    {
        $hex = strtoupper($hex);
        $chars = '0123456789ABCDEF';
        $return = '0';
        for($i = 0; $i < strlen($hex); $i++)
        {
            $current = (string)strpos($chars, $hex[$i]);
            $return = (string)bcmul($return, '16', 0);
            $return = (string)bcadd($return, $current, 0);
        }
        return $return;
    }
    
    function encodeBase58($hex)
    {
        $orighex = $hex;
        $chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
        $hex = decodeHex($hex);
        $return = '';
        while(bccomp($hex, 0) == 1)
        {
            $dv = (string)bcdiv($hex, '58', 0);
            $rem = (integer)bcmod($hex, '58');
            $hex = $dv;
            $return = $return.$chars[$rem];
        }
        $return = strrev($return);
    
        //leading zeros
        for($i = 0; $i < strlen($orighex) && substr($orighex, $i, 2) == '00'; $i += 2)
        {
            $return = '1' . $return;
        }
    
        return $return;
    }
    
    if(!isset($_SERVER['argv'][1]))
    {
        exit("Usage: php convert_bitcoin_private_key_to_wif_format.php private_key\n");
    }
    
    $privateKey = $_SERVER['argv'][1];
    
    //add a 0x80 byte in front of it 
    $buffer = '80' . $privateKey; 
    $extendedKey = $buffer;
    
    //perform SHA-256 hash on the extended key 
    $buffer = strtoupper(hash('sha256', hex2bin($buffer)));
    
    //perform SHA-256 hash on result of SHA-256 hash 
    $buffer = strtoupper(hash('sha256', hex2bin($buffer)));
    
    //take the first 4 bytes of the second SHA-256 hash, this is the checksum 
    $checksum = substr($buffer, 0, 8);
    
    //add the checksum at the end of the extended key
    $buffer = $extendedKey . $checksum;
    
    //convert the result from a byte string into a base58 string
    $buffer = encodeBase58($buffer);
    
    echo($buffer . "\n");
    
    ?>
    

相关问题