Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AES decryption padding with PKCS5 Python

I have been trying to implement AES CBC decryption in Python. Since the ciphered text is not a multiple of 16bytes, padding was necessary. Without padding, this error surfaced

"TypeError: Odd-length string"

But I could not find a proper reference for implementing PKCS5 in PyCrypto Python. Are there any commands to implement this? Thanks

After looking into Marcus's suggestion I did this.

My goal actually is to decrypt a hex message(128bytes) using this code. However, the output is " ?:" which is very small and the unpad command is deleting those bytes. This is the code.

from Crypto.Cipher import AES
BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS) 
unpad = lambda s : s[0:-ord(s[-1])]

class AESCipher:
    def __init__( self, key ):
    self.key = key 

    def encrypt( self, raw ):
        raw = pad(raw)
        iv = raw[:16]
        raw=raw[16:]
        #iv = Random.new().read( AES.block_size )
        cipher = AES.new( self.key, AES.MODE_CBC, iv )
        return ( iv + cipher.encrypt( raw ) ).encode("hex")

    def decrypt( self, enc ):
        iv = enc[:16]
        enc= enc[16:]
        cipher = AES.new(self.key, AES.MODE_CBC, iv )
        return unpad(cipher.decrypt( enc))

mode = AES.MODE_CBC
key = "140b41b22a29beb4061bda66b6747e14"
ciphertext = "4ca00ff4c898d61e1edbf1800618fb2828a226d160dad07883d04e008a7897ee2e4b7465d5290d0c0e6c6822236e1daafb94ffe0c5da05d9476be028ad7c1d81";
key=key[:32]
decryptor = AESCipher(key)
decryptor.__init__(key)
plaintext = decryptor.decrypt(ciphertext)
print plaintext 
like image 793
empyreanphoenix Avatar asked Sep 24 '12 09:09

empyreanphoenix


People also ask

How do you decrypt AES encrypted files in Python?

AES requires a secret passphrase known as a “key” to encrypt/decrypt data. Anybody with the key can decrypt your data, so you need it to be strong and hidden from everyone―only the software program should be able to access it. The key can be either 128, 192, 256, or 512 bit long.

What is PKCS5 padding?

PKCS5 PaddingIf the block length is B then add N padding bytes of value N to make the input length up to the next exact multiple of B . If the input length is already an exact multiple of B then add B bytes of value B . Thus padding of length N between one and B bytes is always added in an unambiguous manner.

Does AES have padding?

AES uses 128-bits (16 bytes), and DES uses 64-bit blocks (8 bytes). The main padding methods are: CMS (Cryptographic Message Syntax). This pads with the same value as the number of padding bytes.

Does AES CBC require padding?

Padding your plaintext is required if you perform AES encryption in ECB/CBC block cipher mode, unless your plaintext is a multiple of the blocksize. You could of course make sure that your plaintext is always precisely N blocks, but in effect you would be creating your own padding mode.


1 Answers

You need to decode your hex encoded value before decryption. If you want to work with hex encoded keys, decode it as well..

Here, this should work.

from Crypto.Cipher import AES
from Crypto import Random

BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS) 
unpad = lambda s : s[0:-ord(s[-1])]

class AESCipher:
    def __init__( self, key ):
        """
        Requires hex encoded param as a key
        """
        self.key = key.decode("hex")

    def encrypt( self, raw ):
        """
        Returns hex encoded encrypted value!
        """
        raw = pad(raw)
        iv = Random.new().read(AES.block_size);
        cipher = AES.new( self.key, AES.MODE_CBC, iv )
        return ( iv + cipher.encrypt( raw ) ).encode("hex")

    def decrypt( self, enc ):
        """
        Requires hex encoded param to decrypt
        """
        enc = enc.decode("hex")
        iv = enc[:16]
        enc= enc[16:]
        cipher = AES.new(self.key, AES.MODE_CBC, iv )
        return unpad(cipher.decrypt( enc))

if __name__== "__main__":
    key = "140b41b22a29beb4061bda66b6747e14"
    ciphertext = "4ca00ff4c898d61e1edbf1800618fb2828a226d160dad07883d04e008a7897ee2e4b7465d5290d0c0e6c6822236e1daafb94ffe0c5da05d9476be028ad7c1d81"
    key=key[:32]
    decryptor = AESCipher(key)
    plaintext = decryptor.decrypt(ciphertext)
    print "%s" % plaintext
like image 183
Akdeniz Avatar answered Oct 12 '22 13:10

Akdeniz