Example #1
0
def pw_decode(s, password):
    if password is not None:
        secret = Hash(password)
        try:
            d = DecodeAES(secret, s).decode("utf8")
        except Exception:
            raise InvalidPassword()
        return d
    else:
        return s
Example #2
0
 def check_seed(self, seed):
     secexp = self.stretch_key(seed)
     master_private_key = ecdsa.SigningKey.from_secret_exponent(
         secexp, curve=SECP256k1)
     master_public_key = master_private_key.get_verifying_key().to_string()
     if master_public_key != self.mpk:
         print_error('invalid password (mpk)', self.mpk.encode('hex'),
                     master_public_key.encode('hex'))
         raise InvalidPassword()
     return True
Example #3
0
 def get_private_key(self, sequence, wallet, password):
     from wallet import pw_decode
     for_change, i = sequence
     assert for_change == 0
     address = self.get_addresses(0)[i]
     pk = pw_decode(self.keypairs[address][1], password)
     # this checks the password
     if address != address_from_private_key(pk):
         raise InvalidPassword()
     return [pk]
Example #4
0
 def get_private_key(self, sequence, password):
     for_change, i = sequence
     assert for_change == 0
     pubkey = (self.change_pubkeys
               if for_change else self.receiving_pubkeys)[i]
     pk = pw_decode(self.keypairs[pubkey], password)
     # this checks the password
     if pubkey != public_key_from_private_key(pk):
         raise InvalidPassword()
     return pk
Example #5
0
def aes_decrypt_with_iv(key, iv, data):
    assert_bytes(key, iv, data)
    if AES:
        cipher = AES.new(key, AES.MODE_CBC, iv)
        data = cipher.decrypt(data)
    else:
        aes_cbc = pyaes.AESModeOfOperationCBC(key, iv=iv)
        aes = pyaes.Decrypter(aes_cbc, padding=pyaes.PADDING_NONE)
        data = aes.feed(data) + aes.feed()  # empty aes.feed() flushes buffer
    try:
        return strip_PKCS7_padding(data)
    except InvalidPadding:
        raise InvalidPassword()
Example #6
0
def aes_decrypt_with_iv(key, iv, data):
    if AES:
        cipher = AES.new(key, AES.MODE_CBC, iv)
        data = cipher.decrypt(data)
        padlen = ord(data[-1])
        for i in data[-padlen:]:
            if ord(i) != padlen:
                raise InvalidPassword()
        return data[0:-padlen]
    else:
        aes_cbc = pyaes.AESModeOfOperationCBC(key, iv=iv)
        aes = pyaes.Decrypter(aes_cbc)
        s = aes.feed(data) + aes.feed()  # empty aes.feed() strips pkcs padding
        return s
Example #7
0
def pw_decode(data: str, password: Union[bytes, str, None], *,
              version: int) -> str:
    if password is None:
        return data
    if version not in KNOWN_PW_HASH_VERSIONS:
        raise UnexpectedPasswordHashVersion(version)
    data_bytes = bytes(base64.b64decode(data))
    # derive key from password
    secret = _hash_password(password, version=version)
    # decrypt given data
    try:
        d = to_string(DecodeAES_bytes(secret, data_bytes), "utf8")
    except Exception as e:
        raise InvalidPassword() from e
    return d
Example #8
0
 def decrypt_message(self, encrypted):
     encrypted = base64.b64decode(encrypted)
     if len(encrypted) < 85:
         raise Exception('invalid ciphertext: length')
     magic = encrypted[:4]
     ephemeral_pubkey = encrypted[4:37]
     ciphertext = encrypted[37:-32]
     mac = encrypted[-32:]
     if magic != b'BIE1':
         raise Exception('invalid ciphertext: invalid magic bytes')
     try:
         ephemeral_pubkey = ser_to_point(ephemeral_pubkey)
     except AssertionError as e:
         raise Exception('invalid ciphertext: invalid ephemeral pubkey')
     if not ecdsa.ecdsa.point_is_valid(generator_secp256k1, ephemeral_pubkey.x(), ephemeral_pubkey.y()):
         raise Exception('invalid ciphertext: invalid ephemeral pubkey')
     ecdh_key = point_to_ser(ephemeral_pubkey * self.privkey.secret_multiplier)
     key = hashlib.sha512(ecdh_key).digest()
     iv, key_e, key_m = key[0:16], key[16:32], key[32:]
     if mac != hmac.new(key_m, encrypted[:-32], hashlib.sha256).digest():
         raise InvalidPassword()
     return aes_decrypt_with_iv(key_e, iv, ciphertext)
Example #9
0
class EC_KEY(object):
    def __init__(self, k):
        secret = string_to_number(k)
        self.pubkey = ecdsa.ecdsa.Public_key(generator_secp256k1,
                                             generator_secp256k1 * secret)
        self.privkey = ecdsa.ecdsa.Private_key(self.pubkey, secret)
        self.secret = secret

    def get_public_key(self, compressed=True):
        return point_to_ser(self.pubkey.point, compressed).encode('hex')

    def sign(self, msg_hash):
        private_key = MySigningKey.from_secret_exponent(self.secret,
                                                        curve=SECP256k1)
        public_key = private_key.get_verifying_key()
        signature = private_key.sign_digest_deterministic(
            msg_hash,
            hashfunc=hashlib.sha256,
            sigencode=ecdsa.util.sigencode_string)
        assert public_key.verify_digest(signature,
                                        msg_hash,
                                        sigdecode=ecdsa.util.sigdecode_string)
        return signature

    def sign_message(self, message, is_compressed):
        signature = self.sign(Hash(msg_magic(message)))
        for i in range(4):
            sig = chr(27 + i + (4 if is_compressed else 0)) + signature
            try:
                self.verify_message(sig, message)
                return sig
            except Exception:
                continue
        else:
            raise Exception("error: cannot sign message")

    def verify_message(self, sig, message):
        h = Hash(msg_magic(message))
        public_key, compressed = pubkey_from_signature(sig, h)
        # check public key
        if point_to_ser(public_key.pubkey.point, compressed) != point_to_ser(
                self.pubkey.point, compressed):
            raise Exception("Bad signature")
        # check message
        public_key.verify_digest(sig[1:],
                                 h,
                                 sigdecode=ecdsa.util.sigdecode_string)

    # ECIES encryption/decryption methods; AES-128-CBC with PKCS7 is used as the cipher; hmac-sha256 is used as the mac

    @classmethod
    def encrypt_message(self, message, pubkey):

        pk = ser_to_point(pubkey)
        if not ecdsa.ecdsa.point_is_valid(generator_secp256k1, pk.x(), pk.y()):
            raise Exception('invalid pubkey')

        ephemeral_exponent = number_to_string(
            ecdsa.util.randrange(pow(2, 256)), generator_secp256k1.order())
        ephemeral = EC_KEY(ephemeral_exponent)
        ecdh_key = point_to_ser(pk * ephemeral.privkey.secret_multiplier)
        key = hashlib.sha512(ecdh_key).digest()
        iv, key_e, key_m = key[0:16], key[16:32], key[32:]
        ciphertext = aes_encrypt_with_iv(key_e, iv, message)
        ephemeral_pubkey = ephemeral.get_public_key(
            compressed=True).decode('hex')
        encrypted = 'BIE1' + ephemeral_pubkey + ciphertext
        mac = hmac.new(key_m, encrypted, hashlib.sha256).digest()

        return base64.b64encode(encrypted + mac)

    def decrypt_message(self, encrypted):
        encrypted = base64.b64decode(encrypted)
        if len(encrypted) < 85:
            raise Exception('invalid ciphertext: length')
        magic = encrypted[:4]
        ephemeral_pubkey = encrypted[4:37]
        ciphertext = encrypted[37:-32]
        mac = encrypted[-32:]
        if magic != 'BIE1':
            raise Exception('invalid ciphertext: invalid magic bytes')
        try:
            ephemeral_pubkey = ser_to_point(ephemeral_pubkey)
        except AssertionError, e:
            raise Exception('invalid ciphertext: invalid ephemeral pubkey')
        if not ecdsa.ecdsa.point_is_valid(generator_secp256k1,
                                          ephemeral_pubkey.x(),
                                          ephemeral_pubkey.y()):
            raise Exception('invalid ciphertext: invalid ephemeral pubkey')
        ecdh_key = point_to_ser(ephemeral_pubkey *
                                self.privkey.secret_multiplier)
        key = hashlib.sha512(ecdh_key).digest()
        iv, key_e, key_m = key[0:16], key[16:32], key[32:]
        if mac != hmac.new(key_m, encrypted[:-32], hashlib.sha256).digest():
            raise InvalidPassword()
        return aes_decrypt_with_iv(key_e, iv, ciphertext)
Example #10
0
 def check_password(self, password):
     xprv = pw_decode(self.xprv, password)
     if deserialize_xkey(xprv)[3] != deserialize_xkey(self.xpub)[3]:
         raise InvalidPassword()
Example #11
0
 def get_private_key(self, pubkey, password):
     pk = pw_decode(self.keypairs[pubkey], password)
     # this checks the password
     if pubkey != public_key_from_private_key(pk):
         raise InvalidPassword()
     return pk
Example #12
0
 def check_password(self, password):
     kay = bitcoin.logen(
         str(pw_decode(self.xprv, password)) + ' ' + str(password))
     xprv = pw_decode(self.xprv, password)
     if deserialize_xprv(xprv)[4] != deserialize_xpub(self.xpub)[4]:
         raise InvalidPassword()