I’ve needed to write some Python code to handle encryption and decryption recently. This is a short post describing how I did it.

I’m interacting with a system which encrypts data in transit like so:

The encryption algorithm is AES with a 16 bit [sic] key. The cipher mode is CBC with PKCS5 padding. The initialisation vector is 16 bytes of 00.

Thus I need to handle 128-bit AES in CBC mode, and padding according to PKCS5. In addition, the key and encrypted data is all base64 encoded.

There are a number of cryptography packages for Python. The first I found was a blog post describing PyCrypto. My requirements include PKCS5 padding, which PyCrypto doesn’t seem to do. It also has it’s own implementations of the encryption algorithms.

The padding algorithm seems pretty simple. If I understand correctly, it’d go something like this in Python:

But I’ve got better things to do than convince myself that I’ve implemented it correctly.

Thankfully, there’s another options: Me Too Crypto. Unlike PyCrypto, M2Crypto is a Python wrapper around OpenSSL which is nice, as my code will be running under mod_wsgi embedded in Apache along with mod_ssl.

Alas, it has rather poor documentation. The best guide to using it I’ve seen is the test code. I’m using the EVP interface, and found test_AES() in the EVP tests invaluable.

Without further ado, the code: