Search code examples
pythonpython-3.xencryptionaespyopenssl

Python and OpenSSL: unable to decrypt


I have found a small piece of code capable of encrypt (and decrypt) files in AES (128bit) CBC mode. It work flawlessy even in decryption so I belived that OpenSSL would be capable (of course) od decrypting my files but it seems impossibile. I get the "Error reading input files"

import os, random, struct
from Crypto.Cipher import AES

def encrypt_file(key, in_filename, out_filename=None, chunksize=64*1024):
    """ Encrypts a file using AES (CBC mode) with the
        given key.

        key:
            16, 24 or 32 bytes long

        in_filename:
            Name of the input file

        out_filename:
            If None, '<in_filename>.enc' will be used.

        chunksize:
            Sets the size of the chunk which the function
            uses to read and encrypt the file.
            Chunksize must be divisible by 16.
        """
    if not out_filename:
            out_filename = in_filename + '.enc'

    iv = ''.join(chr(random.randint(0, 0xFF)) for i in range(16))
    encryptor = AES.new(key, AES.MODE_CBC, iv)
    filesize = os.path.getsize(in_filename)

    with open(in_filename, 'rb') as infile:
        with open(out_filename, 'wb') as outfile:
            outfile.write(struct.pack('<Q', filesize))
            outfile.write(iv)

            while True:
                chunk = infile.read(chunksize)
                if len(chunk) == 0:
                    break
                elif len(chunk) % 16 != 0:
                    chunk += ' ' * (16 - len(chunk) % 16)

                outfile.write(encryptor.encrypt(chunk))

The error is the same ever time: "Error reading input files". How is it possibile? The commands I use is this:

openssl aes-128-cbc -d -in test_enc.txt -out test_dec.txt

Why doesn't work?


Solution

  • OpenSSL uses its own file format. In particular, there's a Salted__ header, as well as a salt that's used to derive the IV (i.e. the IV is not directly stored with the encrypted data).

    You can find some hints in https://scottlinux.com/2013/10/13/how-to-encrypt-a-file-with-openssl/ and in https://crypto.stackexchange.com/questions/3298/is-there-a-standard-for-openssl-interoperable-aes-encryption, but they don't describe the actual format.

    You might be able to examine the OpenSSL code to figure that out, but the bottom line is that OpenSSL uses its own file format and you have to use it if you want OpenSSL to decrypt your files.