File Encryption Using AES and PyCrypto in Python 3

I use PyCrypto to encrypt a binary using AES in CBC mode (Python 3.2.3 64-bit and PyCrypto 2.6). Using this code: http://eli.thegreenplace.net/2010/06/25/aes-encryption-of-files-in-python-with-pycrypto/

But running the following error: ValueError: IV should be 16 bytes long.

Here is the code:

def encryptFile(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_file: Input file out_file: If None, a StringIO will be returned. 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)) 

I tried searching and experimenting, but can't get it to work. Python is pretty new to me, and it's also encryption. Any help would be greatly appreciated. Thanks in advance.

+4
source share
2 answers

As the PyCrypto API says, IV should be a byte string , not a text string.

Your piece of code will work fine in Python 2 because it is the same thing (that is, they are all the str class, unless you work with Unicode text). In Python 3, these are two completely different types: bytes and str .

Therefore, the code should be:

 iv = bytes([ random.randint(0,0xFF) for i in range(16)] ) 

Such code (in addition to being not cryptographically secure, as Federico points out) in Python 2 does not work properly. The following alternative works fine in both cases, it is safe and , it is more effective:

 iv = Random.new().read(16) 
+7
source

I think I'm too late, but simple-crypt provides a simple wrapper around pycrypto that (1) solves your problem and (2) includes a key extension and hmac to detect changes (it uses CTR mode AES256).

+2
source

All Articles