Beispiel #1
0
    def __init__(self, filename, masterkey, aessiv=False):
        if aessiv:
            self.decrypt_block = self.decrypt_siv_block
            self.key = HKDF(masterkey,
                            salt=b"",
                            key_len=64,
                            hashmod=SHA256,
                            context=b"AES-SIV file content encryption")
        else:
            self.decrypt_block = self.decrypt_gcm_block
            self.key = HKDF(masterkey,
                            salt=b"",
                            key_len=32,
                            hashmod=SHA256,
                            context=b"AES-GCM file content encryption")

        self.fp = open(filename, "rb")
        header = self.fp.read(18)

        if len(header) == 0:
            # An empty file is valid. It means that the plaintext file
            # was empty.
            self.fileid = None
        else:
            assert len(header) == 18
            assert header[0:2] == b"\x00\x02"
            self.fileid = header[2:]

        self.blockno = 0
        self.remaining = io.BytesIO()
Beispiel #2
0
def compute_2skd(sk, password, email, p2salt, iterations, algorithm):
    p_debug("** Computing 2SKD\n")

    version = sk[0:2]
    account_id = sk[3:9]
    secret = re.sub('-', '', sk[10:])
    email = email.lower() # simple hack...not doing "proper" normalizaiton...

    email = str.encode(str(email))
    version = str.encode(str(version))

    secret = str.encode(str(secret))
    account_id = str.encode(str(account_id))

    algorithm = str.encode(str(algorithm))

    p_str('Password', password)
    p_str('Email', email)
    p_str('Secret Key', sk)
    p_str('   Version', version)
    p_str('   AcctID', account_id)
    p_str('   Secret', secret)
    p_str('Algorithm', algorithm)
    p_str('Iterations (p2c)', iterations)
    p_str('Salt (p2s)', opb64e(p2salt))

    p_data('Salt (decoded)', p2salt, dump=False)

    hkdf_pass_salt = HKDF(p2salt, 32, email, SHA256, 1, algorithm)

    p_debug('\nHKDF(ikm=p2s, len=32, salt=email, hash=SHA256, count=1, info=algorithm)')
    p_data('HKDF out: pass salt', hkdf_pass_salt, dump=False)

    password = str.encode(str(password))
    password_key = hashlib.pbkdf2_hmac('sha256', password, hkdf_pass_salt, iterations, dklen=32)

    p_debug('\nPBKDF2(sha256, password, salt=HKDF_salt, iterations=p2c, 32 bytes)')
    p_data('Derived password key', password_key, dump=False)

    p_debug('\nHKDF(ikm=secret, len=32, salt=AcctID, hash=SHA256, count=1, info=version)')
    hkdf_key = HKDF(secret, 32, account_id, SHA256, 1, 'A3')
    p_data('HKDF out: secret key', hkdf_key, dump=False)

    final_key = ''

    for x in range(0,32): 

        a = ord(password_key[x])
        b = ord(hkdf_key[x])
        c = a^b
        final_key = final_key + chr(c)

    p_debug('\nXOR PBKDF2 output and SecretKey HKDF output')
    p_data('Final 2SKD out', final_key, dump=False)

    return final_key
Beispiel #3
0
    def test2(self):
        ref = HKDF(b("XXXXXX"), 12, b("YYYY"), SHA1)

        # Same output, but this time split over 2 keys
        key1, key2 = HKDF(b("XXXXXX"), 6, b("YYYY"), SHA1, 2)
        self.assertEqual((ref[:6], ref[6:]), (key1, key2))

        # Same output, but this time split over 3 keys
        key1, key2, key3 = HKDF(b("XXXXXX"), 4, b("YYYY"), SHA1, 3)
        self.assertEqual((ref[:4], ref[4:8], ref[8:]), (key1, key2, key3))
Beispiel #4
0
    def test1(self):
        for tv in self._test_vector:
            secret, salt, info, exp = [ t2b(tv[x]) for x in (1,2,3,5) ]
            key_len, hashmod = [ tv[x] for x in (4,0) ]

            output = HKDF(secret, key_len, salt, hashmod, 1, info)
            self.assertEqual(output, exp)
Beispiel #5
0
    def get_masterkey(self, password):
        scrypt = self.config['ScryptObject']
        block = base64.b64decode(self.config['EncryptedKey'])

        scryptkey = hashlib.scrypt(password.encode('utf-8'),
                                   salt=base64.b64decode(scrypt['Salt']),
                                   n=scrypt['N'],
                                   r=scrypt['R'],
                                   p=scrypt['P'],
                                   maxmem=0x7fffffff,
                                   dklen=scrypt['KeyLen'])

        key = HKDF(scryptkey,
                   salt=b"",
                   key_len=32,
                   hashmod=SHA256,
                   context=b"AES-GCM file content encryption")

        assert len(block) > 32
        assert block != CIPHERTEXT_ZERO
        # Layout: [ NONCE | CIPHERTEXT (...) |  TAG  ]
        nonce, tag, ciphertext = block[:16], block[-16:], block[16:-16]
        aes = AES.new(key, AES.MODE_GCM, nonce=nonce)
        aes.update(struct.pack(">Q", 0))
        return aes.decrypt_and_verify(ciphertext, tag)
Beispiel #6
0
def encrypt(k, pt, ad):
    kd_out = HKDF(k, salt = (b'\0' * 32), key_len = 80,
                  hashmod = SHA256.new(), context = b'kdf_encrypt_info')
    enc_key = SA.keygen('shared', key_mat = kd_out[:32])
    auth_key = SA.keygen('mac', key_mat = kd_out[32:64])
    kd_iv = kd_out[64:]
    ct = SA.encrypt(pt, key = enc_key, iv = kd_iv)
    data, mac = SA.sign(ad + ct, key = auth_key)
    return ct + mac
Beispiel #7
0
    def test_verify(self, tv):
        self._id = "Wycheproof HKDF Test #%d (%s, %s)" % (tv.id, tv.comment, tv.filename)

        try:
            key = HKDF(tv.ikm, tv.size, tv.salt, tv.hash_module, 1, tv.info)
        except ValueError:
            assert not tv.valid
        else:
            if key != tv.okm:
                assert not tv.valid
            else:
                assert tv.valid
                self.warn(tv)
Beispiel #8
0
def decrypt(k, ct, ad):
    kd_out = HKDF(k, salt = (b'\0' * 32), key_len = 80,
                  hashmod = SHA256.new(), context = b'kdf_encrypt_info')
    enc_key = SA.keygen('shared', key_mat = kd_out[:32])
    auth_key = SA.keygen('mac', key_mat = kd_out[32:64])
    kd_iv = kd_out[64:]
    ct_iv = ct[:16]
    ct_mac = ct[-32:]
    ct_ct = ct[:-32]
    assert kd_iv == ct_iv
    verdict = SA.verify((b'\0' + ad + ct_ct, ct_mac), key = auth_key)
    if verdict != None:
        return SA.decrypt(ct_ct, key = enc_key)
    else:
        raise Exception
Beispiel #9
0
    def test_hdkf(self):
        derived = HKDF(b'secret', 32, b'', SHA256).hex()
        self.assertEqual(
            derived,
            "2f34e5ff91ec85d53ca9b543683174d0cf550b60d5f52b24c97b386cfcf6cbbf")

        k1 = PrivateKey(secret=bytes([2]))
        self.assertEqual(k1.to_int(), 2)

        k2 = PrivateKey(secret=bytes([3]))
        self.assertEqual(k2.to_int(), 3)

        self.assertEqual(encapsulate(k1, k2.public_key),
                         decapsulate(k1.public_key, k2))
        self.assertEqual(
            encapsulate(k1, k2.public_key).hex(),
            "6f982d63e8590c9d9b5b4c1959ff80315d772edd8f60287c9361d548d5200f82")
Beispiel #10
0
def derive_key(key_material, salt, info):
    """
    Derive a fixed-size (64-byte) key for use in cryptographic operations.

    The key is derived using HKDF with the SHA-512 hash function. See
    https://tools.ietf.org/html/rfc5869.

    :type key_material: str or bytes
    :type salt: bytes
    :type info: bytes
    """
    if not isinstance(key_material, bytes):
        key_material = key_material.encode()

    return HKDF(
        master=key_material,
        key_len=64,
        salt=salt,
        hashmod=SHA512,
        num_keys=1,
        context=info,
    )
Beispiel #11
0
def kdf(secret, key_len):
    from Cryptodome.Protocol.KDF import HKDF
    from Cryptodome.Hash import SHA512
    return HKDF(as_bytes(secret), key_len, None, SHA512)
Beispiel #12
0
def decapsulate(public_key: PublicKey, peer_private_key: PrivateKey) -> bytes:
    shared_point = public_key.multiply(peer_private_key.secret)
    master = public_key.format(compressed=False) + shared_point.format(
        compressed=False)
    derived = HKDF(master, AES_KEY_BYTES_LEN, b'', SHA256)
    return derived
Beispiel #13
0
def kdf(KM):
    F = b'\xff' * 32
    s = b'\0' * 32
    info = b'x3dh info'
    return HKDF(KM, salt = s, key_len = 32,
                hashmod = SHA256.new(), context = info)