This script extracts address-private key pairs from an unencrypted Bitcoin wallet.dat file. Uncomment the line to include compressed addresses.
import binascii
import hashlib
import codecs
import mmap
import sys
import ecdsa
import base58
def base58str(address_hex):
alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
b58_string = ''
leading_zeros = len(address_hex) - len(address_hex.lstrip('0'))
address_int = int(address_hex, 16)
while address_int > 0:
digit = address_int % 58
digit_char = alphabet[digit]
b58_string = digit_char + b58_string
address_int //= 58
ones = leading_zeros // 2
for one in range(ones):
b58_string = '1' + b58_string
return b58_string
def priv_to_addr(address_hex, compressed):
signing_key = ecdsa.SigningKey.from_string(address_hex, curve=ecdsa.SECP256k1)
verifying_key = signing_key.get_verifying_key()
if not compressed:
public_key = bytes.fromhex("04") + verifying_key.to_string()
else:
public_key_x = verifying_key.to_string()[0:32]
public_key_y = verifying_key.to_string()[32:]
if int(binascii.hexlify(public_key_y),16) % 2 == 0:
public_key = bytes.fromhex("02") + public_key_x
else:
public_key = bytes.fromhex("03") + public_key_x
sha256_1 = hashlib.sha256(public_key)
ripemd160 = hashlib.new("ripemd160")
ripemd160.update(sha256_1.digest())
hashed_public_key = bytes.fromhex("00") + ripemd160.digest()
checksum_full = hashlib.sha256(hashlib.sha256(hashed_public_key).digest()).digest()
checksum = checksum_full[:4]
bin_addr = hashed_public_key + checksum
result_addr = base58.b58encode(bin_addr).decode("utf-8")
return result_addr
def main():
f = open(sys.argv[1], "rb")
mm = mmap.mmap(f.fileno(),0,prot=mmap.PROT_READ)
currindex = mm.find(b'\x02\x01\x01\x04\x20')
privkeyList = set()
while(currindex > -1):
mm.seek(currindex+5)
privkeyList.add(mm.read(32))
currindex = mm.find(b'\x02\x01\x01\x04\x20')
f.close()
print("Found [" + str(len(privkeyList)) + "] possible keys")
for key in privkeyList:
PKuncomp = b'80'+ binascii.hexlify(key)
uncomp_address = priv_to_addr(key,False)
PKcomp = PKuncomp + b'01'
comp_address = priv_to_addr(key,True)
PKuncomp_sha256_1 = hashlib.sha256(codecs.decode(PKuncomp, 'hex'))
PKuncomp_sha256_2 = hashlib.sha256(PKuncomp_sha256_1.digest())
checksum_uncomp = codecs.encode(PKuncomp_sha256_2.digest(), 'hex')[0:8]
uncomp_PK = PKuncomp + checksum_uncomp
PKcomp_sha256_1 = hashlib.sha256(codecs.decode(PKcomp, 'hex'))
PKcomp_sha256_2 = hashlib.sha256(PKcomp_sha256_1.digest())
checksum_comp = codecs.encode(PKcomp_sha256_2.digest(), 'hex')[0:8]
comp_PK = PKcomp + checksum_comp
WIF_uncomp = base58str(uncomp_PK.decode("utf-8"))
WIF_comp = base58str(comp_PK.decode("utf-8"))
print(uncomp_address + ":" + WIF_uncomp)
# print(comp_address + ":" + WIF_comp)
if __name__ == "__main__":
main()