Search code examples
pythonencryptionaespbkdf2

pbkdf2 generates wrong key and iv in python for AES-256-CBC decryption


I want to reimplement data decryption which is currently running in a batch script into python.

openssl enc -d -aes-256-cbc -md sha256 -salt -pbkdf2 -in input.tgz.enc -out output.tgz -pass file:symetric_key

This is working. I am new to the topic and was told that openssl itself calculates the IV, salt and key it needs out of the symetric.key

Is it correct that it reads the first line without the \n of the file?

This my code current code:

encrypted_recording = b'Salted__"\xu5\xu32\df\......'
with open(symetric_key_path, "rb") as f:
            # ascii bytestring
            symetric_key = f.readline()
            symetric_key = symetric_key.strip(b"\n")

# the first line of symetric_key is supposed to be the pw, like in openssl bash cmd
def get_key_and_iv(encrypted_recording, symetric_key):
    """get key and iv with PBKDF2 and create AES-cipher object later on"""
    # Get 8 bytes salt from encrypted file
    salt = encrypted_recording[8:16]
    # Generate IV and key using PBKDF2, salt and symetric key 
    key_and_iv = hashlib.pbkdf2_hmac('sha256', symetric_key, salt, 64000, 48)
    key = key_and_iv[:32]
    iv = key_and_iv[32:48]
    return key, iv

def decrypt_encrypted_recording(encrypted_recording, key, iv):
    # Create AES cipher object
    cipher = AES.new(key=key, mode=AES.MODE_CBC, iv=iv)
    # get rid of salt
    encrypted_recording = encrypted_recording[16:]
    # Decrypt encrpyted recording
    decrypted_recording = cipher.decrypt(encrypted_recording)
    decrypted_recording = unpad(decrypted_recording, block_size=AES.block_size)
    return decrypted_recording


I have a running batch file where I can see the iv and key as hex value. When converting them with binascii.unhexlify(iv) and binascii.unhexlify(key), the decrypt_encrypted_recording function works fine. Key and IV which are generated are wrong. Does anybody know why?

The files are encrypted with the same commands like in the decryption, so mostly default values.

Thank you in advance!

I tried different iteration numbers, taking the symetric_key with and without \n as password. The symetric key as whole file is definitely the correct one. No Encoding done with the encrypted data before and after encryption.


Solution

  • I was able to solve the issue. The problem was neither the PBKDF2 implemenation (with 10000 iterations) nor the cipher decryption. The password is a bystestring having hex escape sequences. So stripping out the hex escape sequences to get the first line (because "-pass file: path_to_file" in openssl bashcommand takes the first line of the provided file as password) was my solution.

           with open(symetric_key_path, "rb") as f:
            symetric_key = f.readline()
            # strip out escape sequences in hex to get first line
            symetric_key = symetric_key.strip(b"\x0A")
            symetric_key = symetric_key.strip(b"\x00")