[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