def load(self): try: self.struct = proto_wallet.Wallet() self.struct.ParseFromString(open(self.filename, 'r').read()) except IOError: # Wallet load failed, let's initialize new one self.struct = proto_wallet.Wallet(algo=proto.ELECTRUM, secexp='') self._deserialize_secexp()
def get_wallet(filename, password): with open(filename, 'rb') as f: data = base64.b64decode(f.read()) assert (data[:8] == b'Salted__') salt = data[8:16] key, iv = derive_key_and_iv(password, salt, 32, AES.block_size) cipher = AES.new(key, AES.MODE_CBC, iv) len(data[AES.block_size:]) padded_plain = cipher.decrypt(data[AES.block_size:]) pad_len = padded_plain[-1] if isinstance(pad_len, str): pad_len = ord(pad_len) pbdata = padded_plain[:-pad_len] w = wallet_pb2.Wallet() w.ParseFromString(pbdata) return w
def load_wallet(wallet_file, get_password_fn): """load and if necessary decrypt a bitcoinj wallet file :param wallet_file: an open bitcoinj wallet file :type wallet_file: file :param get_password_fn: a callback returning a password that's called iff one is required :type get_password_fn: function :return: the Wallet protobuf message or None if no password was entered when required :rtype: wallet_pb2.Wallet """ wallet_file.seek(0) magic_bytes = wallet_file.read(12) wallet_file.seek(0, os.SEEK_END) wallet_size = wallet_file.tell() wallet_file.seek(0) if magic_bytes[2:6] != b"org." and wallet_size % 16 == 0: import pylibscrypt takes_long = not pylibscrypt._done # if a binary library wasn't found, this'll take a while ciphertext = wallet_file.read() assert len(ciphertext) % 16 == 0 password = get_password_fn(takes_long) if not password: return None # Derive the encryption key salt = '\x35\x51\x03\x80\x75\xa3\xb0\xc5' key = pylibscrypt.scrypt(password.encode('utf_16_be'), salt, olen=32) # Decrypt the wallet ( v0.5.0+ ) try: plaintext = aes256_cbc_decrypt(ciphertext[16:], key, ciphertext[:16]) if plaintext[2:6] != b"org.": raise ValueError('incorrect password') except ValueError as e: if e.args[0] == 'incorrect password': # Decrypt the wallet ( < v0.5.0 ) iv = '\xa3\x44\x39\x1f\x53\x83\x11\xb3\x29\x54\x86\x16\xc4\x89\x72\x3e' plaintext = aes256_cbc_decrypt(ciphertext, key, iv) global multibit_hd_password multibit_hd_password = password # Else it's not whole-file encrypted else: password = None plaintext = wallet_file.read() # Parse the wallet protobuf pb_wallet = wallet_pb2.Wallet() try: pb_wallet.ParseFromString(plaintext) except Exception as e: msg = 'not a wallet file: ' + str(e) if password: msg = "incorrect password (or " + msg + ")" raise ValueError(msg) f = open('parsed_wallet.txt','w') f.write(pb_wallet.__str__()) f.close() foundAddr = [] for trans in pb_wallet.transaction: if trans.pool == 4: print("--------------------------------------------------------------------------------") print("TXID: " + binascii.hexlify(trans.hash)) for out in trans.transaction_output: print("") faddr = bitcoin.bin_to_b58check(bitcoin.deserialize_script(out.script_bytes)[2]) print("Addr: " + faddr) foundAddr.append(faddr) print("Amt: " + str(out.value * 0.00000001) + " BTC") print("") print("--------------------------------------------------------------------------------") seed = None sys.stdout.write('Finding Seed....') salt = pb_wallet.encryption_parameters.salt dkey = pylibscrypt.scrypt(password.encode('utf_16_be'), salt, olen=32) for wkey in pb_wallet.key: if wkey.type == 3: seed = aes256_cbc_decrypt(wkey.encrypted_deterministic_seed.encrypted_private_key, dkey, wkey.encrypted_deterministic_seed.initialisation_vector) break if not seed: print("No DETERMINISTIC_MNEMONIC seed found!") return None else: print("Done!") xprv = bitcoin.bip32_master_key(seed) xprvReceive = bitcoin.bip32_ckd(bitcoin.bip32_ckd(xprv, 2**31),0) #m/0'/0 xprvChange = bitcoin.bip32_ckd(bitcoin.bip32_ckd(xprv, 2**31),1) #m/0'/1 rcvAddr = [] chgAddr = [] rcvPrivKey = [] chgPrivKey = [] sys.stdout.write("Generating Addresses/Keys.") for x in range(0,1000): if x % 10 == 0: sys.stdout.write(".") childprivReceive = bitcoin.bip32_ckd(xprvReceive, x) childprivChange = bitcoin.bip32_ckd(xprvChange, x) pkeyReceive = bitcoin.bip32_extract_key(childprivReceive) pkeyChange = bitcoin.bip32_extract_key(childprivChange) #addressReceive = privtoaddr(pkeyReceive) #addressChange = privtoaddr(pkeyChange) rcvAddr.append(bitcoin.privtoaddr(pkeyReceive)) chgAddr.append(bitcoin.privtoaddr(pkeyChange)) rcvPrivKey.append(bitcoin.encode_privkey(pkeyReceive, 'wif_compressed')) chgPrivKey.append(bitcoin.encode_privkey(pkeyChange, 'wif_compressed')) print("Done!") print("--------------------------------------------------------------------------------") for addy in foundAddr: if addy in rcvAddr: print("") print("Found Address: " + addy) print("PrivateKey: " + rcvPrivKey[rcvAddr.index(addy)]) elif addy in chgAddr: print("") print("Found Change Address: " + addy) print("PrivateKey: " + chgPrivKey[chgAddr.index(addy)]) else: print("") print("Address not found: " + addy) print("") print("--------------------------------------------------------------------------------") return pb_wallet
def load_wallet(wallet_file, get_password_fn): """load and if necessary decrypt a bitcoinj wallet file :param wallet_file: an open bitcoinj wallet file :type wallet_file: file :param get_password_fn: a callback returning a password that's called iff one is required :type get_password_fn: function :return: the Wallet protobuf message or None if no password was entered when required :rtype: wallet_pb2.Wallet """ wallet_file.seek(0) magic_bytes = wallet_file.read(12) wallet_file.seek(0, os.SEEK_END) wallet_size = wallet_file.tell() wallet_file.seek(0) if magic_bytes[2:6] != b"org." and wallet_size % 16 == 0: takes_long = not pylibscrypt._done # if a binary library wasn't found, this'll take a while ciphertext = wallet_file.read() assert len(ciphertext) % 16 == 0 password = get_password_fn(takes_long) if not password: return None # Derive the encryption key salt = '\x35\x51\x03\x80\x75\xa3\xb0\xc5' key = pylibscrypt.scrypt(password.encode('utf_16_be'), salt, olen=32) # Decrypt the wallet ( v0.5.0+ ) try: plaintext = aes256_cbc_decrypt(ciphertext[16:], key, ciphertext[:16]) if plaintext[2:6] != b"org.": raise ValueError('incorrect password') except ValueError as e: if e.args[0] == 'incorrect password': # Decrypt the wallet ( < v0.5.0 ) iv = '\xa3\x44\x39\x1f\x53\x83\x11\xb3\x29\x54\x86\x16\xc4\x89\x72\x3e' plaintext = aes256_cbc_decrypt(ciphertext, key, iv) global multibit_hd_password multibit_hd_password = password # Else it's not whole-file encrypted else: print("File NOT Encrypted") password = None plaintext = wallet_file.read() # Parse the wallet protobuf pb_wallet = wallet_pb2.Wallet() try: pb_wallet.ParseFromString(plaintext) except Exception as e: msg = 'not a wallet file: ' + str(e) if password: msg = "incorrect password (or " + msg + ")" raise ValueError(msg) f = open('parsed_wallet.txt','w') f.write(pb_wallet.__str__()) f.close() print("--------------------------------------------------------------------------------") if pb_wallet.encryption_type == 2: print("Keys are encrypted") takes_long = not pylibscrypt._done # if a binary library wasn't found, this'll take a while password = get_password_fn(takes_long) if not password: return None salt = pb_wallet.encryption_parameters.salt dkey = pylibscrypt.scrypt(password.encode('utf_16_be'), salt, olen=32) for enckeys in pb_wallet.key: ciphertext = enckeys.encrypted_data.encrypted_private_key iv = enckeys.encrypted_data.initialisation_vector privkey = aes256_cbc_decrypt(ciphertext, dkey, iv) print("") print("Pubkey: " + bitcoin.pubtoaddr(enckeys.public_key)) print("Privkey: " + bitcoin.encode_privkey(privkey, 'wif_compressed')) elif pb_wallet.encryption_type == 1: print("Keys NOT encrypted") for enckeys in pb_wallet.key: print("") print("Pubkey: " + bitcoin.pubtoaddr(enckeys.public_key)) print("Privkey: " + bitcoin.encode_privkey(enckeys.secret_bytes, 'wif_compressed')) print("") print("--------------------------------------------------------------------------------") return pb_wallet
def load_wallet(wallet_file, get_password_fn): """load and if necessary decrypt a bitcoinj wallet file :param wallet_file: an open bitcoinj wallet file :type wallet_file: file :param get_password_fn: a callback returning a password that's called iff one is required :type get_password_fn: function :return: the Wallet protobuf message or None if no password was entered when required :rtype: wallet_pb2.Wallet """ #// The format of the encrypted ".cipher" file is: #// 7 magic bytes 'mendoza' in ASCII. #// 1 byte version number of format - initially set to 0 (actually 0x00!) #// 8 bytes salt #// 16 bytes iv #// rest of file is the encrypted byte data wallet_file.seek(0) magic_bytes = wallet_file.read(7) version = wallet_file.read(1) wallet_file.seek(0, os.SEEK_END) wallet_size = wallet_file.tell() wallet_file.seek(0) if magic_bytes[0:7] == b"mendoza" and version == "\x00" and wallet_size % 16 == 0: print("") print("MultiBit Classic Cipher file found") print("") takes_long = not pylibscrypt._done # if a binary library wasn't found, this'll take a while ciphertext = wallet_file.read() assert len(ciphertext) % 16 == 0 password = get_password_fn(takes_long) if not password: return None # Derive the encryption key salt = ciphertext[8:16] key = pylibscrypt.scrypt(password.encode('utf_16_be'), salt, olen=32) iv = ciphertext[16:32] # Decrypt the wallet ( v0.5.0+ ) plaintext = aes256_cbc_decrypt(ciphertext[32:], key, iv) if plaintext[2:6] != b"org.": raise ValueError('incorrect password') # Else it's not a cipher file encrypted else: print("File is NOT a Multibit Classic Cipher File") return # Parse the wallet protobuf pb_wallet = wallet_pb2.Wallet() try: pb_wallet.ParseFromString(plaintext) except Exception as e: msg = 'not a wallet file: ' + str(e) if password: msg = "incorrect password (or " + msg + ")" raise ValueError(msg) f = open('parsed_cipher_wallet.txt','w') f.write(pb_wallet.__str__()) f.close() print("--------------------------------------------------------------------------------") if pb_wallet.encryption_type == 2: print("Keys are encrypted") takes_long = not pylibscrypt._done # if a binary library wasn't found, this'll take a while password = get_password_fn(takes_long) if not password: return None salt = pb_wallet.encryption_parameters.salt dkey = pylibscrypt.scrypt(password.encode('utf_16_be'), salt, olen=32) for enckeys in pb_wallet.key: ciphertext = enckeys.encrypted_data.encrypted_private_key iv = enckeys.encrypted_data.initialisation_vector privkey = aes256_cbc_decrypt(ciphertext, dkey, iv) print("") print("Pubkey: " + bitcoin.pubtoaddr(enckeys.public_key)) print("Privkey: " + bitcoin.encode_privkey(privkey, 'wif_compressed')) elif pb_wallet.encryption_type == 1: print("Keys NOT encrypted") for enckeys in pb_wallet.key: print("") print("Pubkey: " + bitcoin.pubtoaddr(enckeys.public_key)) print("Privkey: " + bitcoin.encode_privkey(enckeys.secret_bytes, 'wif_compressed')) print("") print("--------------------------------------------------------------------------------") return pb_wallet