Exemplo n.º 1
0
    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()
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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