Sometimes I just need some encryption, so I wrote a script that fits some cases. The functions use the python Crypto library.
The security of the used encryption is ok, I wrote a PBKDF2-like Key Derivation Function, that hashes the password before truncating and using it as the AES key. The encryption function does not add random padding. This means an attacker can guess how long the plaintext was. Additionally, CBC is a non-authenticated mode, therefore if somebody flips a bit in your ciphertext the decryption routine won’t notice. This usually means an attacker can flip one bit, but the remaining blocks will be corrupted. So flipping a bit in the last block is easy. Moreover 13’370 derivation rounds might be too much or not enough for you.
def AESencrypt(password, plaintext, base64=False): import hashlib, os from Crypto.Cipher import AES SALT_LENGTH = 32 DERIVATION_ROUNDS=13370 BLOCK_SIZE = 16 KEY_SIZE = 32 MODE = AES.MODE_CBC salt = os.urandom(SALT_LENGTH) iv = os.urandom(BLOCK_SIZE) paddingLength = 16 - (len(plaintext) % 16) paddedPlaintext = plaintext+chr(paddingLength)*paddingLength derivedKey = password for i in range(0,DERIVATION_ROUNDS): derivedKey = hashlib.sha256(derivedKey+salt).digest() derivedKey = derivedKey[:KEY_SIZE] cipherSpec = AES.new(derivedKey, MODE, iv) ciphertext = cipherSpec.encrypt(paddedPlaintext) ciphertext = ciphertext + iv + salt if base64: import base64 return base64.b64encode(ciphertext) else: return ciphertext.encode("hex") def AESdecrypt(password, ciphertext, base64=False): import hashlib from Crypto.Cipher import AES SALT_LENGTH = 32 DERIVATION_ROUNDS=13370 BLOCK_SIZE = 16 KEY_SIZE = 32 MODE = AES.MODE_CBC if base64: import base64 decodedCiphertext = base64.b64decode(ciphertext) else: decodedCiphertext = ciphertext.decode("hex") startIv = len(decodedCiphertext)-BLOCK_SIZE-SALT_LENGTH startSalt = len(decodedCiphertext)-SALT_LENGTH data, iv, salt = decodedCiphertext[:startIv], decodedCiphertext[startIv:startSalt], decodedCiphertext[startSalt:] derivedKey = password for i in range(0, DERIVATION_ROUNDS): derivedKey = hashlib.sha256(derivedKey+salt).digest() derivedKey = derivedKey[:KEY_SIZE] cipherSpec = AES.new(derivedKey, MODE, iv) plaintextWithPadding = cipherSpec.decrypt(data) paddingLength = ord(plaintextWithPadding[-1]) plaintext = plaintextWithPadding[:-paddingLength] return plaintext a = AESencrypt("password", "ABC") print AESdecrypt("password", a)