Given the popularity of Python, at first I was disappointed that no answer to this question was found. It took me a lot of different answers to this board, as well as to other resources, to get it right. I thought I could share the results for future reference and possibly consider; I am by no means a specialist in cryptography! However, the code below works without problems:
from hashlib import md5 from Crypto.Cipher import AES from Crypto import Random def derive_key_and_iv(password, salt, key_length, iv_length): d = d_i = '' while len(d) < key_length + iv_length: d_i = md5(d_i + password + salt).digest() d += d_i return d[:key_length], d[key_length:key_length+iv_length] def decrypt(in_file, out_file, password, key_length=32): bs = AES.block_size salt = in_file.read(bs)[len('Salted__'):] key, iv = derive_key_and_iv(password, salt, key_length, bs) cipher = AES.new(key, AES.MODE_CBC, iv) next_chunk = '' finished = False while not finished: chunk, next_chunk = next_chunk, cipher.decrypt(in_file.read(1024 * bs)) if len(next_chunk) == 0: padding_length = ord(chunk[-1]) chunk = chunk[:-padding_length] finished = True out_file.write(chunk)
Using:
with open(in_filename, 'rb') as in_file, open(out_filename, 'wb') as out_file: decrypt(in_file, out_file, password)
If you see an opportunity to improve this or expand it to be more flexible (for example, make it work without salt or provide compatibility with Python 3), feel free to do it.
Note
This answer was also used for encryption in Python using the same scheme. Since then, I have removed this part to discourage anyone from using it. DO NOT encrypt more data this way, because it is NOT secure by today's standards. You should ONLY use decryption for no other reason than DELAY COMPATIBILITY i.e. When you have no other choice. Want to encrypt? Use NaCl / libsodium if possible.
Thijs van Dien May 26 '13 at 16:47 2013-05-26 16:47
source share