检查php中的比特币wallet.dat密码散列



我想将密码短语与特定比特币wallet.dat文件中使用bitcoin2john.py生成的哈希进行匹配。

因此,首先我创建了一个wallet.dat,其密码短语为";位";。

bitcoin2john.py为此wallet.dat文件生成以下输出:$比特币$64$12c098515dc4f4140786e352f05d3065f17a2ca8f15c5f1c93923dc7146380c6$16b99a74fa7b536$135174$2$00$2$00

用hashcat破解那个散列是可能的。Haschcat返回正确的密码短语:$比特币$64$12c098515dc4f4140786e352f05d3065f17a2ca8f15c5f1c93923dc7146380c6$146b99a74fa7b536$135174$2$00$2$00:比特

现在我想在PHP中做到这一点(已经失败了好几天(:

<?php
$testPassphrase = 'bit';
/*
* Hash from wallet.dat with passphrase: "bit"
* (Could be cracked by hashcat)
*/
$passHash = '$bitcoin$64$12c098515dc4f4140786e352f05d3065f17a2ca8f15c5f1c93923dc7146380c6$16$146b99a74fa7b536$135174$2$00$2$00';

/*
* Remove hash identifier (not needed)
*/
$passHash = str_replace('$bitcoin$', '', $passHash);

/*
* Split hash into pieces
* ([0] = ??, [1] = passphrase hash, [2] = salt len, [3] = salt, [4] = iteration count, [5] = salt position, [6] = ??, [7] == ??, [8] == ??)
*/
$passHashArray = explode('$', $passHash);

/*
* Combine passphrase and salt
*/
$passToHash = $testPassphrase.$passHashArray[3];

/*
* Hash $passToHash $passHasArray[4] times with SHA512
*/
for($i = 0; $i < $passHashArray[4]; $i++){
$passToHash = hash('SHA512', $passToHash, true);
}

/*
* Get Key and Iv from $passToHash for final encryption
*/
$key = substr($passToHash, 0, 32);
$iv = substr($passToHash, 32, 16);

/*
* final passphrase encryption
*/
if(in_array('aes-256-cbc', openssl_get_cipher_methods())){
$testPassphrase = openssl_encrypt($testPassphrase, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv);
}
/*
* show result (should be: $passHashArray[1] = "12c098515dc4f4140786e352f05d3065f17a2ca8f15c5f1c93923dc7146380c6")
*/
echo bin2hex($testPassphrase);
?>

我浏览了比特币核心代码,看看它是如何做到的。

墙内。ccp(https://github.com/bitcoin/bitcoin/blob/2556a973ed5839c81ad23cc4d3f187f3a777483c/src/wallet/wallet.cpp)在第387行中,函数ChangeWalletPassphrase显示了这些步骤。在crypt.ccp(https://github.com/bitcoin/bitcoin/blob/c7ad94428ab6f54661d7a5441e1fdd0ebf034903/src/wallet/crypter.cpp)在第13行和第39行中,使用了函数BytesToKeySHA512AES和SetKeyFromPassphrase。

这就是我的PHP samle代码所做的;最终口令加密";。

据我通过互联网研究发现,密钥和由此生成的iv随后被用于用AES-256-CBC加密密码短语。你也可以在比特币核心代码中找到这一点。但在那里,似乎不是密码短语,而是主密钥(_vMasterKey(被加密了。但是我没有MasterKey,所以Hashcat(在我的测试场景中(没有。但是,如果对密码短语进行加密,则无法生成正确的哈希。

经过几天的代码试用和错误,我现在在这里寻求帮助。提前感谢您的帮助!

开始吧!

<?php
$testPassphrase = 'bit';
/*
* Hash from wallet.dat with passphrase: "bit"
* (Could be cracked by hashcat)
*/
$passHash = '$bitcoin$64$12c098515dc4f4140786e352f05d3065f17a2ca8f15c5f1c93923dc7146380c6$16$146b99a74fa7b536$135174$2$00$2$00';

/*
* Remove hash identifier (not needed)
*/
$passHash = str_replace('$bitcoin$', '', $passHash);

/*
* Split hash into pieces
* ([0] = ??, [1] = master key, [2] = salt len, [3] = salt, [4] = iteration count, [5] = salt position, [6] = ??, [7] == ??, [8] == ??)
*/
$passHashArray = explode('$', $passHash);

/*
* Combine passphrase and salt
*/
$passToHash = $testPassphrase.hex2bin($passHashArray[3]);

/*
* Hash $passToHash $passHasArray[4] times with SHA512
*/
for($i = 0; $i < $passHashArray[4]; $i++){
$passToHash = hash('SHA512', $passToHash, true);
}

/*
* Get Key and Iv from $passToHash for final encryption
*/
$key = substr($passToHash, 0, 32);
$iv = substr($passToHash, 32, 16);

/*
* final passphrase encryption
*/
if(in_array('aes-256-cbc', openssl_get_cipher_methods())){
if(openssl_decrypt(hex2bin($passHashArray[1]), 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv)){
echo 'password correct';
}else{
echo 'decrypt failed';
}
}
?>

最新更新