Path: blob/master/Authenticated-Encryption/AE-with-MACs/Encrypt-then-MAC/encrypt-then-mac.py
1402 views
"""1An illustration of MAC then Encrypt technique of Authenticated Encryption with MACs2MAC algorithm: CBC-MAC3Encryption: AES in CBC mode4Note that this is only for illustrative purposes (the script is vulnerable to CBC-MAC forgery and more implementation attacks-5even the unpad function is vulnerable!)6"""78from Crypto.Cipher import AES9from os import urandom10from Crypto.Util.number import *1112key = urandom(16)13iv = urandom(16)14mac_key = urandom(16)1516blocksize = 161718def pad(input_str, blocksize):19input_str += chr(blocksize - len(input_str) % blocksize)*(blocksize - len(input_str) % blocksize)20assert len(input_str) % blocksize == 021return input_str2223def unpad(input_str):24return input_str[:-ord(input_str[-1])]2526def cbc_mac_gen(input_str, iv, mac_key, blocksize):27input_str = pad(input_str, blocksize)28obj1 = AES.new(mac_key, AES.MODE_CBC, iv)29auth_tag = obj1.encrypt(input_str)[-blocksize:]30return auth_tag3132def encrypt(input_str, iv, key, blocksize):33input_str = pad(input_str, blocksize)34obj1 = AES.new(key, AES.MODE_CBC, iv)35ciphertext = obj1.encrypt(input_str)36return ciphertext3738def decrypt(ciphertext, iv, key, blocksize):39obj1 = AES.new(key, AES.MODE_CBC, iv)40plaintext = obj1.decrypt(ciphertext)41return unpad(plaintext)4243def encrypt_then_mac(input_str, iv, key, mac_key, blocksize):44ciphertext = encrypt(input_str, iv, key, blocksize)45tag = cbc_mac_gen(ciphertext, iv, mac_key, blocksize)46return ciphertext.encode("hex") + ":" + tag.encode("hex")4748def auth_check(session_cookie, iv, key, mac_key, blocksize):49ciphertext, tag = session_cookie.split(":")50ciphertext = ciphertext.decode("hex")51tag = tag.decode("hex")52if cbc_mac_gen(ciphertext, iv, mac_key, blocksize) == tag:53print "Authentication Successful"54return decrypt(ciphertext, iv, key, blocksize)55else:56print "Authentication Failed"57return 05859str1 = encrypt_then_mac("testplaintext", iv, key, mac_key, 16)60print str161print auth_check(str1, iv, key, mac_key, blocksize)6263