Path: blob/master/Authenticated-Encryption/AE-with-MACs/MAC-then-Encrypt/mac-then-encrypt.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_tag.encode("hex")3132def cbc_mac_auth(input_str, iv, mac_key, blocksize, auth_tag):33input_str = pad(input_str, blocksize)34obj1 = AES.new(mac_key, AES.MODE_CBC, iv)35chk_tag = obj1.encrypt(input_str)[-blocksize:]36if chk_tag == auth_tag:37print "Verification Successful"38return 139else:40print "Verification Failed"41return 04243def encrypt(input_str, iv, key, blocksize):44input_str = pad(input_str, blocksize)45obj1 = AES.new(key, AES.MODE_CBC, iv)46ciphertext = obj1.encrypt(input_str)47return ciphertext.encode("hex")4849def decrypt(ciphertext, iv, key, blocksize):50obj1 = AES.new(key, AES.MODE_CBC, iv)51plaintext = obj1.decrypt(ciphertext)52return unpad(plaintext)5354def mac_then_encrypt(input_str, iv, key, mac_key, blocksize):55tag = cbc_mac_gen(input_str, iv, mac_key, blocksize)56tag = tag.decode("hex")57plaintext = input_str + ":" + tag58ciphertext = encrypt(plaintext, iv, key, blocksize)59return iv.encode("hex") + ":" + ciphertext6061def auth_check(cookie, iv, key, mac_key, blocksize):62iv, ciphertext = cookie.split(":")63iv = iv.decode("hex")64ciphertext = ciphertext.decode("hex")65plaintext = decrypt(ciphertext, iv, key, blocksize)66input_str, auth_tag = plaintext.split(":")67if cbc_mac_auth(input_str, iv, mac_key, blocksize, auth_tag):68print "Plaintext: ", input_str69else:70return "Verification failed, so nothing for you"7172str1 = mac_then_encrypt("testplaintext", iv, key, mac_key, blocksize)73print str174print auth_check(str1, iv, key, mac_key, blocksize)7576