AES-128 CBC decryption in Python

20,583

You are using Python 3, not Python 2. You can't use decode() on strings in Python 3, they are already text, so bytes-to-bytes codecs such as 'hex' can't be applied that way.

Use the binascii module instead:

from binascii import hexlify, unhexlify

key = unhexlify('2b7e151628aed2a6abf7158809cf4f3c')
IV = unhexlify('000102030405060708090a0b0c0d0e0f')
plaintext1 = unhexlify('6bc1bee22e409f96e93d7e117393172a')
plaintext2 = unhexlify('ae2d8a571e03ac9c9eb76fac45af8e51')
plaintext3 = unhexlify('30c81c46a35ce411e5fbc1191a0a52ef')

and

ciphertext_hex = hexlify(ciphertext)
# ...
plaintext_hex = hexlify(plaintext)

So to decode from a hex string to bytes, use binascii.unhexlify(), and to encode back to hex, use binascii.hexlify(). Note that you you can't convert data in-place, you do have to store the result back in a variable (or print out the value, etc.).

Demo:

>>> from Crypto.Cipher import AES
>>> import Crypto.Cipher.AES
>>> from binascii import hexlify, unhexlify
>>> key = unhexlify('2b7e151628aed2a6abf7158809cf4f3c')
>>> IV = unhexlify('000102030405060708090a0b0c0d0e0f')
>>> plaintext1 = unhexlify('6bc1bee22e409f96e93d7e117393172a')
>>> plaintext2 = unhexlify('ae2d8a571e03ac9c9eb76fac45af8e51')
>>> plaintext3 = unhexlify('30c81c46a35ce411e5fbc1191a0a52ef')
>>> cipher = AES.new(key,AES.MODE_CBC,IV)
>>> ciphertext = cipher.encrypt(plaintext1 + plaintext2 + plaintext3)
>>> hexlify(ciphertext)
b'7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b273bed6b8e3c1743b7116e69e22229516'
>>> decipher = AES.new(key,AES.MODE_CBC,IV)
>>> plaintext = decipher.decrypt(ciphertext)
>>> plaintext == plaintext1 + plaintext2 + plaintext3  # test if decryption was successful
True
>>> hexlify(plaintext)
b'6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52ef'
Share:
20,583
Jon Ander Díez
Author by

Jon Ander Díez

Updated on July 09, 2022

Comments

  • Jon Ander Díez
    Jon Ander Díez almost 2 years

    I'm trying to implement this code in python (I'm new to python) and it gives me the following error:

    AttributeError: 'str' object has no attribute 'decode'

    If we remove .decode ('hex') only to avoid such error:

    from itertools import product
    from Crypto.Cipher import AES
    import Crypto.Cipher.AES
    
    key = ('2b7e151628aed2a6abf7158809cf4f3c').decode('hex')
    IV = ('000102030405060708090a0b0c0d0e0f').decode('hex')
    plaintext1 = ('6bc1bee22e409f96e93d7e117393172a').decode('hex')
    plaintext2 = ('ae2d8a571e03ac9c9eb76fac45af8e51').decode('hex')
    plaintext3 = ('30c81c46a35ce411e5fbc1191a0a52ef').decode('hex')
    cipher = AES.new(key, AES.MODE_CBC, IV)
    ciphertext = cipher.encrypt(plaintext1 + plaintext2 + plaintext3)
    (ciphertext).encode('hex')
    decipher = AES.new(key, AES.MODE_CBC, IV)
    plaintext = decipher.decrypt(ciphertext)
    (plaintext).encode('hex')
    

    but it gives me the following error:

    ValueError: IV must be 16 bytes long

    since the algorithm would need the .decode ('hex') that I had to remove

    from itertools import product
    from Crypto.Cipher import AES
    import Crypto.Cipher.AES
    
    key = ('2b7e151628aed2a6abf7158809cf4f3c')
    IV = ('000102030405060708090a0b0c0d0e0f')
    plaintext1 = ('6bc1bee22e409f96e93d7e117393172a')
    plaintext2 = ('ae2d8a571e03ac9c9eb76fac45af8e51')
    plaintext3 = ('30c81c46a35ce411e5fbc1191a0a52ef')
    cipher = AES.new(key,AES.MODE_CBC,IV)
    ciphertext = cipher.encrypt(plaintext1 + plaintext2 + plaintext3)
    (ciphertext).encode('hex')
    decipher = AES.new(key,AES.MODE_CBC,IV)
    plaintext = decipher.decrypt(ciphertext)
    (plaintext).encode('hex')
    

    Does anyone have any idea how I could do to make this code work?

  • Martijn Pieters
    Martijn Pieters over 6 years
    I'd love to hear what is not helpful or wrong about my answer, to deserve a downvote. That way I can improve my answer!
  • rene
    rene over 6 years
    Requesting comments on down votes only gets you more down votes ... have another one ... wait ... no ... scrap that ....
  • Martijn Pieters
    Martijn Pieters over 6 years
    @rene I clean these comments up periodically; sometimes, just sometimes, I do actually get helpful feedback when I ask for it after a dv. I am known to make mistakes from time to time, after all!
  • rene
    rene over 6 years
    Fair enough, I'm allowed one joke a day, right? (I admit it is my poor Dutch humor)
  • Martijn Pieters
    Martijn Pieters over 6 years
    @rene: Dutch humour is underrated, in my personal opinion.
  • Jon Ander Díez
    Jon Ander Díez over 6 years
    Martijn Pieters ♦, I voted positively, you have helped me a lot, without you I would have been looking for the answer for a long time, I am very grateful. Sorry for the misunderstanding