Python
Blockchain
Dump Unencrypted Bitcoin Wallet.dat
This script scans a wallet.dat file for ECDSA private keys using memory mapping. It generates the corresponding compressed/uncompressed Bitcoin addresses and WIF (Wallet Import Format) keys.
⚠️ Warning: Use only on wallets you own. Works on unencrypted files only.
import binascii import hashlib import codecs import mmap import sys import ecdsa import base58 # pip install 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(): if len(sys.argv) < 2: print("Usage: python dump_wallet.py wallet.dat") sys.exit(1) f = open(sys.argv[1], "rb") mm = mmap.mmap(f.fileno(),0,prot=mmap.PROT_READ) # Scanning for key patterns 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', currindex+1) f.close() print(f"Found {len(privkeyList)} possible keys") for key in privkeyList: PKuncomp = b'80'+ binascii.hexlify(key) uncomp_address = priv_to_addr(key, False) 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 WIF_uncomp = base58str(uncomp_PK.decode("utf-8")) print(f"{uncomp_address}:{WIF_uncomp}") if __name__ == "__main__": main()
Requirements
- 1. Python 3.x installed
- 2.
pip install ecdsa base58 - 3. An unencrypted wallet.dat file
How to Run
python wallet_dump.py wallet.dat > keys.txt