1 """Pure-Python AES implementation."""
3 from cryptomath import *
6 from rijndael import rijndael
8 def new(key, mode, IV):
9 return Python_AES(key, mode, IV)
11 class Python_AES(AES):
12 def __init__(self, key, mode, IV):
13 AES.__init__(self, key, mode, IV, "python")
14 self.rijndael = rijndael(key, 16)
17 def encrypt(self, plaintext):
18 AES.encrypt(self, plaintext)
20 plaintextBytes = stringToBytes(plaintext)
21 chainBytes = stringToBytes(self.IV)
23 #CBC Mode: For each block...
24 for x in range(len(plaintextBytes)/16):
26 #XOR with the chaining block
27 blockBytes = plaintextBytes[x*16 : (x*16)+16]
29 blockBytes[y] ^= chainBytes[y]
30 blockString = bytesToString(blockBytes)
33 encryptedBytes = stringToBytes(self.rijndael.encrypt(blockString))
35 #Overwrite the input with the output
37 plaintextBytes[(x*16)+y] = encryptedBytes[y]
39 #Set the next chaining block
40 chainBytes = encryptedBytes
42 self.IV = bytesToString(chainBytes)
43 return bytesToString(plaintextBytes)
45 def decrypt(self, ciphertext):
46 AES.decrypt(self, ciphertext)
48 ciphertextBytes = stringToBytes(ciphertext)
49 chainBytes = stringToBytes(self.IV)
51 #CBC Mode: For each block...
52 for x in range(len(ciphertextBytes)/16):
55 blockBytes = ciphertextBytes[x*16 : (x*16)+16]
56 blockString = bytesToString(blockBytes)
57 decryptedBytes = stringToBytes(self.rijndael.decrypt(blockString))
59 #XOR with the chaining block and overwrite the input with output
61 decryptedBytes[y] ^= chainBytes[y]
62 ciphertextBytes[(x*16)+y] = decryptedBytes[y]
64 #Set the next chaining block
65 chainBytes = blockBytes
67 self.IV = bytesToString(chainBytes)
68 return bytesToString(ciphertextBytes)