Reputation: 219
I have the following code running like a charm
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
key = b'Sixteen byte key'
data = 'some text to encrypt'.encode("UTF-8")
data = pad(data, AES.block_size)
encryptor = AES.new(key, AES.MODE_CBC)
iv = encryptor.IV
decryptor = AES.new(key, AES.MODE_CBC, IV=iv)
ciphertext = encryptor.encrypt(data)
print(ciphertext)
plaintext = decryptor.decrypt(ciphertext)
print(unpad(plaintext, 16))
But when I try to convert to a function I got an padding error. My adapted code is
def cbc(msg, op):
key = b'Sixteen byte key'
encryptor = AES.new(key, AES.MODE_CBC)
iv = encryptor.IV
decryptor = AES.new(key, AES.MODE_CBC, IV=iv)
if op == 1:
data = msg.encode("UTF-8")
data = pad(data, AES.block_size)
ciphertext = encryptor.encrypt(data)
print(ciphertext)
else:
plaintext = decryptor.decrypt(msg)
print(unpad(plaintext, 16))
My log is
Traceback (most recent call last):
File "D:/Google Drive/max/AES.py", line 48, in <module>
cbc(b'*\xd3\xc1Y\xc2f;\xf0\xc0@\xd9E\xc5x\x11\xb4', 2)
File "D:/Google Drive/max/AES.py", line 19, in cbc
print(unpad(plaintext, 16))
File "C:\Users\Evilmaax\AppData\Local\Programs\Python\Python36\lib\site-packages\Crypto\Util\Padding.py", line 90, in unpad
raise ValueError("Padding is incorrect.")
ValueError: Padding is incorrect.
Error occurs in else
statement when I try to decrypt a byte message like *\xd3\xc1Y\xc2f;\xf0\xc0@\xd9E\xc5x\x11\xb4
. Important: This message was generated by the if
statement of same function.
Does anyone know why this happens? __________________________________________________________
EDIT: Using Rob Napier's tip (thank you so much) I solved the problem. If you experiencing the same issue, this is a functional version:
def cbc(key, data, op):
if op == 1:
cipher = AES.new(key, AES.MODE_CBC, iv)
data = key.encrypt(data)
print(f"Coded text: {data}")
else:
decipher = AES.new(key, AES.MODE_CBC, IV=iv)
print(f'Plaintext: {unpad(decipher.decrypt(data), BLOCK_SIZE).decode("utf-8")}')
Upvotes: 2
Views: 1961
Reputation: 299565
You're generating a random IV, which is good, but you then throw it away, which means you can't decrypt the data.
This line creates an encryptor with a random IV:
encryptor = AES.new(key, AES.MODE_CBC)
This line creates a decryptor with the same IV:
decryptor = AES.new(key, AES.MODE_CBC, IV=iv)
That's fine in your initial code, but you don't save the IV anywhere, so when you put it in a function which you call twice, you're trying to decrypt with a different IV than you encrypted with.
You need to save the IV as part of the cipher text, and use it during decryption. If you want an example of such a format, see the RNCryptor spec, and if you want to see an example in Python, see RNCryptor-python.
Upvotes: 2