cbc_recover_key_from_iv.py (1194B)
1 import re 2 from Crypto.Cipher import AES 3 from Crypto import Random 4 5 key = Random.new().read(AES.block_size) 6 7 def encrypt(msg): 8 pad_len = AES.block_size - (len(msg) % AES.block_size) 9 return AES.new(key, AES.MODE_CBC, key).encrypt(msg + ''.join([chr(pad_len) for x in range(pad_len)])) 10 11 def decrypt(cipher): 12 plaintext = AES.new(key, AES.MODE_CBC, key).decrypt(cipher) 13 14 for c in plaintext: 15 if ord(c) >= 128: 16 print "invalid character found: " + plaintext 17 break 18 19 return plaintext 20 21 def xor(a, b): 22 return "".join([chr(ord(x) ^ ord(y)) for (x, y) in zip(a, b)]) 23 24 def encryption_oracle(m): 25 return encrypt("comment1=cooking%20MCs;userdata=" + re.sub("[;|=]", '', m) + ";comment2=%20like%20a%20pound%20of%20bacon") 26 27 plaintext = "hello-admin-truehello-admin-truehello-admin-true" 28 ciphertext = list(encryption_oracle(plaintext)) 29 30 for i in range(AES.block_size): 31 ciphertext[i + AES.block_size] = 'x00' 32 ciphertext[i + AES.block_size + AES.block_size] = ciphertext[i] 33 34 corrupted = decrypt(''.join(ciphertext)) 35 recovered_key = xor(corrupted[:AES.block_size], corrupted[2 * AES.block_size : 3 * AES.block_size]) 36 37 print recovered_key == key