[pycrypto] AES decrypting issues

Dwayne C. Litzenberger dlitz at dlitz.net
Wed Oct 7 21:52:53 CST 2009


On Wed, Oct 07, 2009 at 11:06:46AM -0500, Mike Driscoll wrote:
>Hi,
>
>I am working on a project where I need to decrypt some data that has
>been encrypted with AES. Our webmaster gave me a PHP example that he 
>uses, but I'm supposed to use Python. Here's the PHP code:
>
>$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
>$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
>return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key,
>$data,MCRYPT_MODE_ECB, $iv),"\0");

ECB is insecure.  See the example at:
http://en.wikipedia.org/w/index.php?title=Block_cipher_modes_of_operation&oldid=312409841#Electronic_codebook_.28ECB.29

To decrypt using ECB mode, you define a function like this:

     from Crypto.Cipher import AES

     def decrypt_my_data(key, data):
         if len(key) not in (16, 24, 32):
             raise ValueError("Key must be 16, 24, or 32 bytes")
         if (len(data) % 16) != 0:
             raise ValueError("Message must be a multiple of 16 bytes")
         cipher = AES.new(key, AES.MODE_ECB)
         return cipher.decrypt(data)

To decrypt using CBC mode (which is better than using ECB mode, but of 
course the sender also has to use CBC mode):

     from Crypto.Cipher import AES

     def decrypt_my_data(key, data, iv):
         if len(key) not in (16, 24, 32):
             raise ValueError("Key must be 16, 24, or 32 bytes")
         if (len(data) % 16) != 0:
             raise ValueError("Message must be a multiple of 16 bytes")
         if len(iv) != 16:
             raise ValueError("IV must be 16 bytes")
         cipher = AES.new(key, AES.MODE_ECB, iv)
         return cipher.decrypt(data)

>I've been told on c.l.py that the iv in this case should be 16 bytes.
>
>I tried following the example on this blog by modifying it as needed:
>
>http://www.codekoala.com/blog/2009/aes-encryption-python-using-pycrypto/

Beware: Whoever wrote that doesn't know the difference between the cipher 
block size and the size of the key, and he uses ECB mode.

>But no matter which base64 decode method I use, I get some kind of 
>error: b32decode, b64decode and decodestring all return a padding error 
>whereas b16decode claims that I don't have only 16-bit characters in my 
>data string.

Base64 has nothing to do cryptography.  It just turns binary to printable 
ASCII and back:

     >>> import base64
     >>> x = base64.encodestring("This string contains the unprintable \x00 byte")
     >>> print x
     VGhpcyBzdHJpbmcgY29udGFpbnMgdGhlIHVucHJpbnRhYmxlIAAgYnl0ZQ==

     >>> base64.decodestring(x)
     'This string contains the unprintable \x00 byte'

Cheers,
- Dwayne

-- 
Dwayne C. Litzenberger <dlitz at dlitz.net>
  Key-signing key   - 19E1 1FE8 B3CF F273 ED17  4A24 928C EC13 39C2 5CF7


More information about the pycrypto mailing list