3
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:
            The encryption key - a string that must be
            either 16, 24 or 32 bytes long. Longer keys
            are more secure.

        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. Larger chunk
            sizes can be faster for some files and machines.
            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))

This is how I encrypt file, but if you run it twice or more on the same file it will keep encrypting it no questions asked, I want to add some kind of a if check if it's not already encrypted by AES? Is this possible?

1
  • I agree with Ricky Demer. If the application depends upon knowing if a file is encrypted then I would either choose the authenticated encryption route, or keep a table of file names with a flag with their encryption state.
    – RoraΖ
    Commented Jul 30, 2014 at 14:29

2 Answers 2

2

As mentioned by Valmiky Arquissandas, encrypted text is generally expected to be computationally indistinguishable from random data. Thus, the only publicly known efficient way to do
something like check if a file is "not already encrypted by AES" is to run a randomness test.

However, your application should use authenticated encryption anyway,
and if it does then it can use the verification procedure to determine with very
high accuracy whether or not the file was already encrypted by the same key.

Additionally, as Valmiky also indicated, it can use a custom wrapper to let it distinguish with
very high accuracy between files it already encrypted and files that are independent of it.
(However, given your program's code, it would be easy to create a
file that registers as the former without having been encrypted by it.)

1
1

I haven't looked at your code. However, one thing you should know about strong encryption: encrypted text is supposed to be indistinguishable from random data.

This being said, you can either make a heuristic that uses a statistical test to decide whether the text appears random and thus appears to be encrypted (this also means that you wouldn't be able to purposefully encrypt something that looked random - such as a high-quality password), or you can wrap the encrypted text into something that would identify it as such to your application.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .