[pycrypto] AES decrypting issues

Mike Driscoll mdriscoll at co.marshall.ia.us
Thu Oct 8 09:27:23 CST 2009


Dwayne C. Litzenberger wrote:
> 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
>   

I actually found that article soon after sending my email. I'll 
recommend using CBC or something else.

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


I ran my data through this script and got zero errors, but the output 
was still junk. I'm beginning to think that  I've been given bad 
information.

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

Thanks for the warning!

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

This made me think that maybe the junk I was getting when I decrypted it 
might have just been the binary representation, so I tried using the 
decodestring method as above. That shortened the printed string up a 
lot, but it was still unreadable.

I'll ask my colleague what the deal is and maybe just see if I can use 
https or something.

Thank you for taking the time to explain all this to me.

- Mike Driscoll



More information about the pycrypto mailing list