[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