Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AES CBC mismatch after decryption. #154

Closed
jeevanbmanoj opened this issue Apr 11, 2018 · 2 comments
Closed

AES CBC mismatch after decryption. #154

jeevanbmanoj opened this issue Apr 11, 2018 · 2 comments

Comments

@jeevanbmanoj
Copy link

Hi,
Please help with the following issue I'm facing. Looking forward to your inputs
https://stackoverflow.com/questions/49767968/pycryprodome-aes-cbc-mismatch-after-decryption-in-python

@SolarDon
Copy link

SolarDon commented Apr 12, 2018

If you use MODE_ECB instead of MODE_CBC it works. I have several other examples here:
https://github.com/SolarDon/pycryptodome/tree/master/Examples

from Crypto.Cipher import AES
# Padding for the input string --not related to encryption itself.
BLOCK_SIZE = 16  # Bytes
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * \
                chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
unpad = lambda s: s[:-ord(s[len(s) - 1:])]

key = b'Sixteen byte key'
data = 'Jeevan B Manoj'.encode("UTF-8")
data = pad(data)
#cipher = AES.new(key, AES.MODE_CBC)
cipher = AES.new(key, AES.MODE_ECB)
print("data before encryption")
print(data)
ciphertext = cipher.encrypt(data)
#cipher = AES.new(key, AES.MODE_CBC)
cipher = AES.new(key, AES.MODE_ECB)
plaintext = cipher.decrypt(ciphertext)
print(unpad(plaintext))

@frispete
Copy link
Contributor

@jeevanbmanoj: you missed the random IV, as noted before.

Guys, why aren't you using AEAD modes here? You get:

  • rid of padding
  • tamper resistant encryption

On the downside, you need to handle nonce and mac in the process.

>>> from Crypto.Cipher import AES
>>> key = b'Sixteen byte key'
>>> data = 'Jeevan B Manoj'.encode('utf-8')
>>> cipher = AES.new(key, AES.MODE_GCM)
>>> ciphertext, mac = cipher.encrypt_and_digest(data)
>>> # transfer cipher.nonce, ciphertext and mac
>>> cipher = AES.new(key, AES.MODE_GCM, cipher.nonce)
>>> print(cipher.decrypt_and_verify(ciphertext, mac))
b'Jeevan B Manoj'

nonce and mac are always 16 byte values in these schemes, hence they can be combined with the ciphertext easily.

Please read and understand:
https://blog.cryptographyengineering.com/2012/05/19/how-to-choose-authenticated-encryption/
https://www.pycryptodome.org/en/latest/src/examples.html

BTW, using AEAD, the weakest part is the key, where a KDF like Argon2 could improve the situation significantly.

Here's an example, where these components are used together in action:
https://github.com/frispete/keyrings.cryptfile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants