Example #1
0
def encrypt(privkey, passphrase):
    """ BIP0038 non-ec-multiply encryption. Returns BIP0038 encrypted privkey.

    :param privkey: Private key
    :type privkey: Base58
    :param str passphrase: UTF-8 encoded passphrase for encryption
    :return: BIP0038 non-ec-multiply encrypted wif key
    :rtype: Base58

    """
    privkeyhex = repr(privkey)  # hex
    addr = format(privkey.uncompressed.address, "BTC")
    a = bytes(addr, 'ascii')
    salt = hashlib.sha256(hashlib.sha256(a).digest()).digest()[0:4]
    if "scrypt" in sys.modules:
        key = scrypt.hash(passphrase, salt, 16384, 8, 8)
    else:
        key = pylibscrypt.scrypt(bytes(passphrase, "utf-8"), salt, 16384, 8, 8)
    (derived_half1, derived_half2) = (key[:32], key[32:])
    aes = AES.new(derived_half2)
    encrypted_half1 = _encrypt_xor(privkeyhex[:32], derived_half1[:16], aes)
    encrypted_half2 = _encrypt_xor(privkeyhex[32:], derived_half1[16:], aes)
    " flag byte is forced 0xc0 because Graphene only uses compressed keys "
    payload = (b'\x01' + b'\x42' + b'\xc0' + salt + encrypted_half1 +
               encrypted_half2)
    " Checksum "
    checksum = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4]
    privatkey = hexlify(payload + checksum).decode('ascii')
    return Base58(privatkey)
Example #2
0
    def __init__(self, salt, password):
        salt = _ensure_bytes(salt)
        password = _ensure_bytes(password)
        seed = scrypt(password, salt, SCRYPT_PARAMS['N'], SCRYPT_PARAMS['r'],
                      SCRYPT_PARAMS['p'], SEED_LENGTH)

        super().__init__(seed)
        self.pubkey = Base58Encoder.encode(self.vk)
Example #3
0
    def __init__(self, salt, password, scrypt_params=ScryptParams(4096,16,1)):
        salt = _ensure_bytes(salt)
        password = _ensure_bytes(password)
        seed = scrypt(password, salt,
                      scrypt_params.N, scrypt_params.r, scrypt_params.p,
                      SEED_LENGTH)

        super().__init__(seed)
        self.pubkey = Base58Encoder.encode(self.vk)
Example #4
0
def build_scrypt_key(passphrase, salt):
    coded_passphrase = struct.pack(">" + "H" * len(passphrase),
                                   *[ord(x) for x in passphrase])
    return scrypt(coded_passphrase,
                  salt,
                  N=DEFAULT_N,
                  r=DEFAULT_R,
                  p=DEFAULT_P,
                  olen=DEFAULT_DERIVED_KEY_LENGTH)
Example #5
0
 def __init__(self, email, password):
     salt = ('KeySwarm Profile Signature Key:'.join(email)).encode('utf-8')
     pw = password.encode('utf-8')
     hashed_pw = pyblake2.blake2s(pw).digest()
     seed = pylibscrypt.scrypt(hashed_pw, salt, 2**17, 8, 1, 32)
     self.private_key = ed25519.SigningKey(seed)
     #print("test: " + str(self.private_key.sign(b"hello world", encoding="base64")))
     self.public_key = self.private_key.get_verifying_key()
     self.address = base58.b58encode( self.public_key.to_bytes() + pyblake2.blake2s(self.public_key.to_bytes(), 1).digest() )
     print("Adress: ", (self.address).decode('utf-8'))
Example #6
0
    def from_ewif_hex(cls: Type[SigningKeyType], ewif_hex: str, password: str) -> SigningKeyType:
        """
        Return SigningKey instance from Duniter EWIF in hexadecimal format

        :param ewif_hex: EWIF string in hexadecimal format
        :param password: Password of the encrypted seed
        """
        ewif_bytes = Base58Encoder.decode(ewif_hex)
        if len(ewif_bytes) != 39:
            raise Exception("Error: the size of EWIF is invalid")

        # extract data
        fi = ewif_bytes[0:1]
        checksum_from_ewif = ewif_bytes[-2:]
        ewif_no_checksum = ewif_bytes[0:-2]
        salt = ewif_bytes[1:5]
        encryptedhalf1 = ewif_bytes[5:21]
        encryptedhalf2 = ewif_bytes[21:37]

        # check format flag
        if fi != b"\x02":
            raise Exception("Error: bad format version, not EWIF")

        # checksum control
        checksum = libnacl.crypto_hash_sha256(libnacl.crypto_hash_sha256(ewif_no_checksum))[0:2]
        if checksum_from_ewif != checksum:
            raise Exception("Error: bad checksum of the EWIF")

        # SCRYPT
        password_bytes = password.encode("utf-8")
        scrypt_seed = scrypt(password_bytes, salt, 16384, 8, 8, 64)
        derivedhalf1 = scrypt_seed[0:32]
        derivedhalf2 = scrypt_seed[32:64]

        # AES
        aes = pyaes.AESModeOfOperationECB(derivedhalf2)
        decryptedhalf1 = aes.decrypt(encryptedhalf1)
        decryptedhalf2 = aes.decrypt(encryptedhalf2)

        # XOR
        seed1 = xor_bytes(decryptedhalf1, derivedhalf1[0:16])
        seed2 = xor_bytes(decryptedhalf2, derivedhalf1[16:32])
        seed = bytes(seed1 + seed2)

        # Password Control
        signer = SigningKey(seed)
        salt_from_seed = libnacl.crypto_hash_sha256(
            libnacl.crypto_hash_sha256(
                Base58Encoder.decode(signer.pubkey)))[0:4]
        if salt_from_seed != salt:
            raise Exception("Error: bad Password of EWIF address")

        return cls(seed)
Example #7
0
def encrypt(privkeyhex, addr, passphrase):
    a = bytes(addr, 'ascii')
    salt = hashlib.sha256(hashlib.sha256(a).digest()).digest()[0:4]
    key = scrypt.scrypt(bytes(passphrase, "utf-8"), salt, 16384, 8, 8)
    derived_half1, derived_half2 = key[:32], key[32:]
    aes = AES.new(derived_half2)
    encrypted_half1 = _encrypt_xor(privkeyhex[:32], derived_half1[:16], aes)
    encrypted_half2 = _encrypt_xor(privkeyhex[32:], derived_half1[16:], aes)
    payload = (b'\x01' + b'\x42' + b'\xc0' +
               salt + encrypted_half1 + encrypted_half2)
    checksum = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4]
    privatkey = hexlify(payload + checksum).decode('ascii')
    return Base58(privatkey)
Example #8
0
File: ppm.py Project: kootenpv/ppm
def generate(master_password, keyword, N=2 ** 15):
    # password: Your life depends on this one. I chose to comine 2 of my passwords -> 16 characters
    # salt:     This should be unique per application. E.g. "gmail".
    #           When you need a new just add a 1, then increment
    # N:        Value above 2**14 is considered safe for interactive use
    #           2 ** 20 is used for non-interactive use
    # r:        Memory factor, I chose 8 since it still works on relatively old phone (1G ram)
    # p:        Factor for parallelism, everyone agrees p=1 is the best
    # dkLen:    Argument in pyscrypt, olen: argument in pylibscrypt
    hashed = scrypt(ensure_input(master_password), ensure_input(keyword), N, 8, 1, 32)
    res = codecs.encode(hashed, 'hex').decode('utf-8')[:32]
    res = "!A" + res[:-2]
    return res
Example #9
0
 def to_json(self, pwd):
     salt = base64.b16encode(os.urandom(16))
     pad = bytearray(pylibscrypt.scrypt(pwd, salt, olen=len(self.key)))
     key = bytearray(self.key)
     for i, p in enumerate(pad):
         key[i] = key[i] ^ p
     return json.dumps({
         'key': base64.b16encode(key),
         'salt': salt,
         'h_length': self.h_length,
         'h_hash': self.h_hash,
         't_timeout': self.t_timeout,
         't_zero': self.t_zero,
     })
Example #10
0
    def save_ewif_file(self, path: str, password: str) -> None:
        """
        Save an Encrypted Wallet Import Format file (WIF v2)

        :param path: Path to file
        :param password:
        """
        # version
        version = 1

        # add version to seed
        salt = libnacl.crypto_hash_sha256(
            libnacl.crypto_hash_sha256(
                Base58Encoder.decode(self.pubkey)))[0:4]

        # SCRYPT
        password_bytes = password.encode("utf-8")
        scrypt_seed = scrypt(password_bytes, salt, 16384, 8, 8, 64)
        derivedhalf1 = scrypt_seed[0:32]
        derivedhalf2 = scrypt_seed[32:64]

        # XOR
        seed1_xor_derivedhalf1_1 = bytes(xor_bytes(self.seed[0:16], derivedhalf1[0:16]))
        seed2_xor_derivedhalf1_2 = bytes(xor_bytes(self.seed[16:32], derivedhalf1[16:32]))

        # AES
        aes = pyaes.AESModeOfOperationECB(derivedhalf2)
        encryptedhalf1 = aes.encrypt(seed1_xor_derivedhalf1_1)
        encryptedhalf2 = aes.encrypt(seed2_xor_derivedhalf1_2)

        # add format to final seed (1=WIF,2=EWIF)
        seed_bytes = b'\x02' + salt + encryptedhalf1 + encryptedhalf2

        # calculate checksum
        sha256_v1 = libnacl.crypto_hash_sha256(seed_bytes)
        sha256_v2 = libnacl.crypto_hash_sha256(sha256_v1)
        checksum = sha256_v2[0:2]

        # B58 encode final key string
        ewif_key = Base58Encoder.encode(seed_bytes + checksum)

        # save file
        with open(path, 'w') as fh:
            fh.write(
                """Type: EWIF
Version: {version}
Data: {data}""".format(version=version, data=ewif_key)
            )
Example #11
0
    def from_credentials(cls: Type[SigningKeyType], salt: Union[str, bytes], password: Union[str, bytes],
                         scrypt_params: Optional[ScryptParams] = None) -> SigningKeyType:
        """
        Create a SigningKey object from credentials

        :param salt: Secret salt passphrase credential
        :param password: Secret password credential
        :param scrypt_params: ScryptParams instance
        """
        if scrypt_params is None:
            scrypt_params = ScryptParams()

        salt = ensure_bytes(salt)
        password = ensure_bytes(password)
        seed = scrypt(password, salt, scrypt_params.N, scrypt_params.r, scrypt_params.p, scrypt_params.seed_length)

        return cls(seed)
Example #12
0
 def from_passphrase(cls, email, passphrase):
     """
     This performs key derivation from an email address and passphrase according
     to the miniLock specification.
     
     Specifically, the passphrase is digested with a standard blake2s 32-bit digest,
     then it is passed through scrypt with the email address as salt value using
     N = 217, r = 8, p = 1, L = 32.
     
     The 32-byte digest from scrypt is then used as the Private Key from which
     the public key is derived.
     """
     pp_blake = pyblake2.blake2s(cls.ensure_bytes(passphrase)).digest()
     #pp_scrypt = scrypt.hash(pp_blake, cls.ensure_bytes(email), 2**17, 8, 1, 32)
     pp_scrypt = pylibscrypt.scrypt(pp_blake, cls.ensure_bytes(email), 2**17, 8, 1, 32)
     key = nacl.public.PrivateKey(pp_scrypt)
     return cls(key.public_key, key)
    def __init__(self, salt, password, scrypt_params=None):
        """
        Init a SigningKey object from credentials

        :param str salt: Secret salt passphrase credential
        :param str password: Secret password credential
        :param ScryptParams scrypt_params: ScryptParams instance
        """
        if scrypt_params is None:
            scrypt_params = ScryptParams(4096, 16, 1)

        salt = _ensure_bytes(salt)
        password = _ensure_bytes(password)
        seed = scrypt(password, salt, scrypt_params.N, scrypt_params.r,
                      scrypt_params.p, SEED_LENGTH)

        super().__init__(seed)
        self.pubkey = Base58Encoder.encode(self.vk)
    def __init__(self, salt: Union[str, bytes], password: Union[str, bytes],
                 scrypt_params: Optional[ScryptParams] = None) -> None:
        """
        Create SecretKey key pair instance from salt and password credentials

        :param salt: Salt credential
        :param password: Password credential
        :param scrypt_params: Optional ScriptParams instance
        """
        if scrypt_params is None:
            scrypt_params = ScryptParams()

        salt = ensure_bytes(salt)
        password = ensure_bytes(password)
        seed = scrypt(password, salt, scrypt_params.N, scrypt_params.r, scrypt_params.p, scrypt_params.seed_length)

        super().__init__(seed)
        self.public_key = PublicKey(Base58Encoder.encode(self.pk))
Example #15
0
def decrypt(encrypted_privkey, passphrase):
    """BIP0038 non-ec-multiply decryption. Returns WIF privkey.

    :param Base58 encrypted_privkey: Private key
    :param str passphrase: UTF-8 encoded passphrase for decryption
    :return: BIP0038 non-ec-multiply decrypted key
    :rtype: Base58
    :raises SaltException: if checksum verification failed (e.g. wrong password)

    """

    d = unhexlify(base58decode(encrypted_privkey))
    d = d[2:]  # remove trailing 0x01 and 0x42
    flagbyte = d[0:1]  # get flag byte
    d = d[1:]  # get payload
    assert flagbyte == b'\xc0', "Flagbyte has to be 0xc0"
    salt = d[0:4]
    d = d[4:-4]
    if "scrypt" in sys.modules:
        key = scrypt.hash(passphrase, salt, 16384, 8, 8)
    else:
        key = pylibscrypt.scrypt(bytes(passphrase, "utf-8"), salt, 16384, 8, 8)

    derivedhalf1 = key[0:32]
    derivedhalf2 = key[32:64]
    encryptedhalf1 = d[0:16]
    encryptedhalf2 = d[16:32]
    aes = AES.new(derivedhalf2)
    decryptedhalf2 = aes.decrypt(encryptedhalf2)
    decryptedhalf1 = aes.decrypt(encryptedhalf1)
    privraw = decryptedhalf1 + decryptedhalf2
    privraw = ('%064x' %
               (int(hexlify(privraw), 16) ^ int(hexlify(derivedhalf1), 16)))
    wif = Base58(privraw)
    """ Verify Salt """
    privkey = PrivateKey(format(wif, "wif"))
    addr = format(privkey.uncompressed.address, "BTC")
    a = bytes(addr, 'ascii')
    saltverify = hashlib.sha256(hashlib.sha256(a).digest()).digest()[0:4]
    if saltverify != salt:
        raise SaltException(
            'checksum verification failed! Password may be incorrect.')
    return wif
Example #16
0
def decrypt(encrypted_privkey, passphrase):
    d = unhexlify(base58decode(encrypted_privkey))
    d = d[2:]   # remove trailing 0x01 and 0x42
    flagbyte = d[0:1]  # get flag byte
    d = d[1:]   # get payload
    salt = d[0:4]
    d = d[4:-4]
    key = scrypt.scrypt(bytes(passphrase, "utf-8"), salt, 16384, 8, 8)
    derivedhalf1 = key[0:32]
    derivedhalf2 = key[32:64]
    encryptedhalf1 = d[0:16]
    encryptedhalf2 = d[16:32]
    aes = AES.new(derivedhalf2)
    decryptedhalf2 = aes.decrypt(encryptedhalf2)
    decryptedhalf1 = aes.decrypt(encryptedhalf1)
    privraw = decryptedhalf1 + decryptedhalf2
    privraw = ('%064x' % (int(hexlify(privraw), 16) ^
                          int(hexlify(derivedhalf1), 16)))
    return privraw
Example #17
0
    def __init__(self,
                 salt: Union[str, bytes],
                 password: Union[str, bytes],
                 scrypt_params: Optional[ScryptParams] = None) -> None:
        """
        Create SecretKey key pair instance from salt and password credentials

        :param salt: Salt credential
        :param password: Password credential
        :param scrypt_params: Optional ScriptParams instance
        """
        if scrypt_params is None:
            scrypt_params = ScryptParams()

        salt = ensure_bytes(salt)
        password = ensure_bytes(password)
        seed = scrypt(password, salt, scrypt_params.N, scrypt_params.r,
                      scrypt_params.p, scrypt_params.seed_length)

        super().__init__(seed)
        self.public_key = PublicKey(Base58Encoder.encode(self.pk))
Example #18
0
def encrypt_secret_key(secret,
                       coldkey,
                       public_address,
                       scrypt_N=2**14,
                       scrypt_p=1):
    '''Encrypt a secret exponent using an individual symmetric key. The symmetric
     key is generated from the shared coldwallet key (given as byte string) and
     the public bitcoin address (given in human readable format) using the
     memory-hard scrypt hash. The result is returned in base64 encoding.
  '''
    # Generate a 256 bit symmetric key from the coldwallet key and the public bitcoin address
    symmetric_key = pylibscrypt.scrypt(coldkey,
                                       public_address.encode('ascii'),
                                       olen=32,
                                       N=scrypt_N,
                                       p=scrypt_p)

    # Encrypt the secret exponent with the symmetric key
    encrypted_secret = coldwallet.aes.encrypt_block(secret, symmetric_key)

    # Base64 encode the result
    return base64.b64encode(encrypted_secret).decode('ascii')
Example #19
0
def decrypt_secret_key(code,
                       coldkey,
                       public_address,
                       scrypt_N=2**14,
                       scrypt_p=1):
    '''Decrypt a secret exponent, given in base64 encoding, using an individual
     symmetric key. The symmetric key is generated as above. The result is
     returned as a byte string.
  '''
    # Base64 decode the input
    code = base64.b64decode(code.encode('ascii'))

    # Generate a 256 bit symmetric key from the coldwallet key and the public bitcoin address
    symmetric_key = pylibscrypt.scrypt(coldkey,
                                       public_address.encode('ascii'),
                                       olen=32,
                                       N=scrypt_N,
                                       p=scrypt_p)

    # Decrypt the secret exponent with the symmetric key
    secret = coldwallet.aes.decrypt_block(code, symmetric_key)

    return secret
import pylibscrypt
import sys


SEED_LENGTH = 32  # Length of the key
crypto_sign_BYTES = 64
SCRYPT_PARAMS = {'N': 4096,
                 'r': 16,
                 'p': 1
                 }


def _ensure_bytes(data):
    if isinstance(data, str):
        return bytes(data, 'utf-8')

    return data

if __name__ == '__main__':
    seed = pylibscrypt.scrypt(_ensure_bytes("pass"), _ensure_bytes("salt"),
                    SCRYPT_PARAMS['N'], SCRYPT_PARAMS['r'], SCRYPT_PARAMS['p'],
                    SEED_LENGTH)
    print(seed)
    sys.exit()
Example #21
0
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import os
import threading
from typing import Optional, Dict

from . import util
from .bitcoin import hash_encode, int_to_hex, rev_hex
from .crypto import sha256d
from . import constants
from .util import bfh, bh2u
from .simple_config import SimpleConfig

try:
    import pylibscrypt
    getPoWHash = lambda x: pylibscrypt.scrypt(password=x, salt=x, N=1024, r=1, p=1, olen=32)
except ImportError:
    util.print_msg("Warning: package pylibscrypt not available")


HEADER_SIZE = 80  # bytes
MAX_TARGET = 0x00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff


class MissingHeader(Exception):
    pass

class InvalidHeader(Exception):
    pass

def serialize_header(header_dict: dict) -> str:
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
Example #23
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
Example #24
0
 def dec_key(self, pwd):
     self.key = bytearray(self.key)
     pad = bytearray(pylibscrypt.scrypt(pwd, self.salt, olen=len(self.key)))
     for i, p in enumerate(pad):
         self.key[i] = self.key[i] ^ p
Example #25
0
#!/usr/bin/env python3

# Copyright (c) 2014-2021, Jan Varho
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

from base64 import b16encode

from pylibscrypt import scrypt, scrypt_mcf, scrypt_mcf_check

# Print a raw scrypt hash in hex
print(b16encode(scrypt(b'Hello World', b'salt')))

# Generate an MCF hash with random salt
mcf = scrypt_mcf('Hello World')

# Test it
print(scrypt_mcf_check(mcf, 'Hello World'))
print(scrypt_mcf_check(mcf, 'HelloPyWorld'))

Example #26
0
def main(token):
    # Name of the challenge
    challenge_name = 'password_hashing'

    # Data of the challenge to a dict
    challenge_dict = data_request(challenge_name, token)
    print(challenge_dict)
    print()

    # Unpack the elements
    password = challenge_dict['password'].encode(encoding='UTF-8')
    print(f'password: {password}')
    salt = base64.b64decode(challenge_dict['salt'])  #decode from base64
    print(f'salt: {salt}')
    print(f"salt: {salt.decode(encoding = 'ISO-8859-1')}")
    # PBKDF parameters
    hash_pbkdf2 = challenge_dict['pbkdf2']['hash']
    iterations_pbkdf2 = challenge_dict['pbkdf2']['rounds']
    # scrypt parameters
    scrypt_N = challenge_dict['scrypt']['N']
    scrypt_p = challenge_dict['scrypt']['p']
    scrypt_r = challenge_dict['scrypt']['r']
    scrypt_buflen = challenge_dict['scrypt']['buflen']
    _control = challenge_dict['scrypt']['_control']

    # SHA256
    pass_sha256 = sha256()
    pass_sha256.update(password)
    pass_sha256 = pass_sha256.hexdigest()
    print(f'SHA256: {pass_sha256}')

    # HMAC-SHA256
    pass_hmac = hmac.new(salt, msg=password, digestmod=sha256).hexdigest()
    print(f'HMAC-SHA256: {pass_hmac}')

    # PBKDF-SHA256
    pass_pbkdf2 = pbkdf2_hmac(hash_pbkdf2, password, salt, iterations_pbkdf2)
    pass_pbkdf2 = str(hexlify(pass_pbkdf2), encoding='UTF-8')
    print(f'PBKDF-SHA256: {pass_hmac}')

    # scrypt
    pass_scrypt = pylibscrypt.scrypt(password,
                                     salt,
                                     N=scrypt_N,
                                     r=scrypt_r,
                                     p=scrypt_p,
                                     olen=32)

    pass_scrypt = str(hexlify(pass_scrypt), encoding='UTF-8')
    print(f'scrypt: {pass_scrypt}')

    # Dict for the solution
    challenge_solution = {
        'sha256': pass_sha256,
        'hmac': pass_hmac,
        'pbkdf2': pass_pbkdf2,
        'scrypt': pass_scrypt
    }

    # Solution POST
    return solution_post(challenge_name, token, challenge_solution)
Example #27
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
Example #28
0
#!/usr/bin/env python

# Copyright (c) 2014-2015, Jan Varho
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

from base64 import b16encode

from pylibscrypt import scrypt, scrypt_mcf, scrypt_mcf_check

# Print a raw scrypt hash in hex
print(b16encode(scrypt(b'Hello World', b'salt')))

# Generate an MCF hash with random salt
mcf = scrypt_mcf(b'Hello World')

# Test it
print(scrypt_mcf_check(mcf, b'Hello World'))
print(scrypt_mcf_check(mcf, b'HelloPyWorld'))