opensslpythonkey3des

How to recover key and iv for files encrypted by OpenSSL using 3DES encryption?


I know there are some answers for similar question, but those seems for AES encryption only, and I got different result when I use python for key derivation.

Now I have passphrase and the salt (from encrypted file by OpenSSL previously using 3DES). I can simply calculate the key and iv by OpenSSL, but I want to implement the key derivation into my python.

This is from OpenSSL output and I believe I should get the same result after key derivation using python:

# openssl enc -des3 -pass pass:cfe4ec9fcec928d51d243855a094b05ebb7bc870 -S 3AA6A64F87764632 -P
salt=3AA6A64F87764632
key=6A8E552A81763B15EC9E1430FAB774C7B5113AFD89E6F03C
iv =DE2CFC91DC61E734

I used this code into my python:

...
print("password is", password.hexdigest())
...
D1=hashlib.md5(password.digest() + openssl_salt).digest()
D2=hashlib.md5(D1 + password.digest() + openssl_salt).digest()
D3=hashlib.md5(D2 + password.digest() + openssl_salt).digest()
key=D1+D2
iv=D3
print ('salt:', openssl_salt.hex())
print ('key:', key.hex())
print ('iv:', iv.hex())

and here's my result, it's obviously different and the key/iv length is also wrong:

password is cfe4ec9fcec928d51d243855a094b05ebb7bc870
...
salt: 3aa6a64f87764632
key: 49096a6dca92f70c88e92a9d67062b8ae70223e432e23a4ee9abd3531d35e1aa
iv: 964f7299c4b960a1264863a23fbbf20b

I think maybe those codes are for AES key derivation, not for 3DES. Could anyone advise?


Solution

  • Looking at this post and the documentation for the KDF used by openssl enc, it seems you are quite close to the solution.

    1. The password cfe... is just encoded to bytes as ASCII text, not as a hex string.
    2. The key is 24 bytes, the IV is 8, and the MD5 digest is 16, so we only need two rounds.

    Putting it together:

    >>> password = 'cfe4ec9fcec928d51d243855a094b05ebb7bc870'.encode()
    >>> salt = bytes.fromhex('3AA6A64F87764632')
    >>> d1 = hashlib.md5(password+salt)
    >>> d2 = hashlib.md5(d1.digest()+password+salt)
    >>> keymatter = d1.digest() + d2.digest()
    >>> key = keymatter[:24].hex().upper()
    >>> iv = keymatter[24:32].hex().upper()
    >>> print(f'key: {key}\nIV:  {iv}')
    key: 6A8E552A81763B15EC9E1430FAB774C7B5113AFD89E6F03C
    IV:  DE2CFC91DC61E734