Padding error encrypting AES CBC mode with Pycrypto

Asked

Viewed 163 times

1

I have the following code working perfectly:

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 trying to turn it into a function the result presents padding error. Code adapted to a function:

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)) 

Error message:

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.

The error at the else, when I pass a byte message *\xd3\xc1Y\xc2f;\xf0\xc0@\xd9E\xc5x\x11\xb4 by parameter. The strange thing is that the message was generated with exactly the same code, with the if prior to else in question.

Does anyone have any idea what might be going on?

1 answer

1


To whom it may concern, follow the way I solved the problem with this answer.

In my job I was generating a iv random at each execution, which is good, however, was not keeping this iv. So when I was going to do the decryption I resorted to a new iv random; what made the padding not hit.

The solution was to declare a iv fixed to both encrypt and decrypt. Follows the organization of the code after change:

iv = b'*\30a\xc1Y\xc2f;\9=1/\xc0@\xd9E\js38\x11\xb4'
def cbc(chave, msg, op):
if op == 1:
    cifra = AES.new(chave, AES.MODE_CBC, iv)
    msg = cifra.encrypt(msg)
    print(f"Mensagem cifrada: {msg}")
else:
    decifra = AES.new(chave, AES.MODE_CBC, IV=iv)
    print(f'Mensagem decifrada: {unpad(decifra.decrypt(msg), BLOCK_SIZE).decode("utf-8")}')
  • Using a fixed IR is unsafe! You need to generate a random IR and send it along with the message. Nor should it use only encryption, but authenticated encryption, such as GCM

Browser other questions tagged

You are not signed in. Login or sign up in order to post.