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

时间:2013-11-18 19:01:27

标签: php sha256 bitcoin

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

尝试在此处使用此示例在PHP中执行此操作,但我在第3步陷入困境。

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

我从第2步800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D

获取扩展密钥

和SHA256吧。

我应该根据第3步获得8147786C4D15106333BF278D71DADAF1079EF2D2440A4DDE37D747DED5403592,但我得到E2E4146A36E9C455CF95A4F259F162C353CD419CC3FD0E69AE36D7D1B6CD2C09

我做错了什么?

2 个答案:

答案 0 :(得分:3)

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

"800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D"

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

hex2bin是你的朋友。

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

DEMO:https://eval.in/69440

另一个例子:

<?php
$key = '0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D';
$binKey = hex2bin($key);

$binKey = hex2bin(80).$binKey;

echo hash('sha256', $binKey);

DEMO:https://eval.in/69443

答案 1 :(得分: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");

?>