#!/usr/bin/python __author__ = "Michael Rightmire" __copyright__ = "Copyright 2013, UTR Enterprises" __credits__ = ["Michael Rightmire"] __license__ = "UTR Enterprises" __version__ = "0.9.0" __maintainer__ = "Michael Rightmire" __email__ = "RightmireM@UTR.Net" __status__ = "Beta" import Crypto.Util.randpool as crandom from Crypto.Cipher import AES import hashlib # salt size in bytes SALT_SIZE = 16 # number of iterations in the key generation NUMBER_OF_ITERATIONS = 20 # the size multiple required for AES AES_MULTIPLE = 16 def generate_key(password, salt, iterations): assert iterations > 0 key = password + salt for i in range(iterations): key = hashlib.sha256(key).digest() return key def pad_text(text, multiple): extra_bytes = len(text) % multiple padding_size = multiple - extra_bytes padding = chr(padding_size) * padding_size padded_text = text + padding return padded_text def unpad_text(padded_text): padding_size = ord(padded_text[-1]) text = padded_text[:-padding_size] return text def encrypt(plaintext, password): salt = crandom.RandomPool(SALT_SIZE) salt = salt.get_bytes(SALT_SIZE) key = generate_key(password, salt, NUMBER_OF_ITERATIONS) cipher = AES.new(key, AES.MODE_ECB) padded_plaintext = pad_text(plaintext, AES_MULTIPLE) ciphertext = cipher.encrypt(padded_plaintext) ciphertext_with_salt = salt + ciphertext return ciphertext_with_salt def decrypt(ciphertext, password): salt = ciphertext[0:SALT_SIZE] ciphertext_sans_salt = ciphertext[SALT_SIZE:] key = generate_key(password, salt, NUMBER_OF_ITERATIONS) cipher = AES.new(key, AES.MODE_ECB) padded_plaintext = cipher.decrypt(ciphertext_sans_salt) plaintext = unpad_text(padded_plaintext) return plaintext