How to do PGP in Python (generate keys, encrypt/decrypt)

You don’t need PyCrypto or PyMe, fine though those packages may be – you will have all kinds of problems building under Windows. Instead, why not avoid the rabbit-holes and do what I did? Use gnupg 1.4.9. You don’t need to do a full installation on end-user machines – just gpg.exe and iconv.dll from the distribution are sufficient, and you just need to have them somewhere in the path or accessed from your Python code using a full pathname. No changes to the registry are needed, and everything (executables and data files) can be confined to a single folder if you want.

There’s a module GPG.py which was originally written by Andrew Kuchling, improved by Richard Jones and improved further by Steve Traugott. It’s available here, but as-is it’s not suitable for Windows because it uses os.fork(). Although originally part of PyCrypto, it is completely independent of the other parts of PyCrypto and needs only gpg.exe/iconv.dll in order to work.

I have a version (gnupg.py) derived from Traugott’s GPG.py, which uses the subprocess module. It works fine under Windows, at least for my purposes – I use it to do the following:

  • Key management – generation, listing, export etc.
  • Import keys from an external source (e.g. public keys received from a partner company)
  • Encrypt and decrypt data
  • Sign and verify signatures

The module I’ve got is not ideal to show right now, because it includes some other stuff which shouldn’t be there – which means I can’t release it as-is at the moment. At some point, perhaps in the next couple of weeks, I hope to be able to tidy it up, add some more unit tests (I don’t have any unit tests for sign/verify, for example) and release it (either under the original PyCrypto licence or a similar commercial-friendly license). If you can’t wait, go with Traugott’s module and modify it yourself – it wasn’t too much work to make it work with the subprocess module.

This approach was a lot less painful than the others (e.g. SWIG-based solutions, or solutions which require building with MinGW/MSYS), which I considered and experimented with. I’ve used the same (gpg.exe/iconv.dll) approach with systems written in other languages, e.g. C#, with equally painless results.

P.S. It works with Python 2.4 as well as Python 2.5 and later. Not tested with other versions, though I don’t foresee any problems.

Leave a Comment