1"""Pure-Python AES implementation.""" 2 3from cryptomath import * 4 5from AES import * 6from rijndael import rijndael 7 8def new(key, mode, IV): 9 return Python_AES(key, mode, IV) 10 11class Python_AES(AES): 12 def __init__(self, key, mode, IV): 13 AES.__init__(self, key, mode, IV, "python") 14 self.rijndael = rijndael(key, 16) 15 self.IV = IV 16 17 def encrypt(self, plaintext): 18 AES.encrypt(self, plaintext) 19 20 plaintextBytes = stringToBytes(plaintext) 21 chainBytes = stringToBytes(self.IV) 22 23 #CBC Mode: For each block... 24 for x in range(len(plaintextBytes)/16): 25 26 #XOR with the chaining block 27 blockBytes = plaintextBytes[x*16 : (x*16)+16] 28 for y in range(16): 29 blockBytes[y] ^= chainBytes[y] 30 blockString = bytesToString(blockBytes) 31 32 #Encrypt it 33 encryptedBytes = stringToBytes(self.rijndael.encrypt(blockString)) 34 35 #Overwrite the input with the output 36 for y in range(16): 37 plaintextBytes[(x*16)+y] = encryptedBytes[y] 38 39 #Set the next chaining block 40 chainBytes = encryptedBytes 41 42 self.IV = bytesToString(chainBytes) 43 return bytesToString(plaintextBytes) 44 45 def decrypt(self, ciphertext): 46 AES.decrypt(self, ciphertext) 47 48 ciphertextBytes = stringToBytes(ciphertext) 49 chainBytes = stringToBytes(self.IV) 50 51 #CBC Mode: For each block... 52 for x in range(len(ciphertextBytes)/16): 53 54 #Decrypt it 55 blockBytes = ciphertextBytes[x*16 : (x*16)+16] 56 blockString = bytesToString(blockBytes) 57 decryptedBytes = stringToBytes(self.rijndael.decrypt(blockString)) 58 59 #XOR with the chaining block and overwrite the input with output 60 for y in range(16): 61 decryptedBytes[y] ^= chainBytes[y] 62 ciphertextBytes[(x*16)+y] = decryptedBytes[y] 63 64 #Set the next chaining block 65 chainBytes = blockBytes 66 67 self.IV = bytesToString(chainBytes) 68 return bytesToString(ciphertextBytes) 69