GPG-encrypted files with python

Occasionally, I want to save some data in an encrypted file from python. Using a context manager, its possible to do this quite easily and in a way where unencrypted data is never saved to disk.

I use the context manager decorator to define an encrypted file method as follows:

import StringIO
from contextlib import contextmanager

@contextmanager
def encFile(file_name, passphrase):
    a = StringIO()
    yield a
    KEYRING = './keyring.gpg'
    SECRET_KEYRING = './secring.gpg'
    GPGBINARY = 'gpg'
    gpg = gnupg.GPG(gnupghome='.', gpgbinary=GPGBINARY, keyring=KEYRING,
                    secret_keyring=SECRET_KEYRING, options=['--throw-keyids',
                    '--personal-digest-preferences=sha256','--s2k-digest-algo=sha256'])
    gpg.encoding = 'latin-1'
    ciphertext = gpg.encrypt(a.getvalue(), recipients=None, symmetric='AES256',
                             armor=False, always_trust=True, passphrase=passphrase)
    a.close()
    with open(file_name, 'wb') as f:
        f.write(ciphertext.data)

and a decrypted file method:

import StringIO
from contextlib import contextmanager

@contextmanager
def decFile(file_name, passphrase):
    KEYRING = './keyring.gpg'
    SECRET_KEYRING = './secring.gpg'
    GPGBINARY = 'gpg'
    gpg = gnupg.GPG(gnupghome='.', gpgbinary=GPGBINARY, keyring=KEYRING,
                    secret_keyring=SECRET_KEYRING, options=['--throw-keyids',
                    '--personal-digest-preferences=sha256','--s2k-digest-algo=sha256'])
    gpg.encoding = 'latin-1'
    with open(file_name, 'rb') as f:
        ciphertext = f.read()
    plaintext = gpg.decrypt(ciphertext, passphrase=passphrase, always_trust=True)
    a = StringIO(plaintext)
    a.seek(0)
    yield a
    a.close()

Now, in my code, I can just do:

with encFile(file_name, passphrase) as f:
    f.write(stuff)

or

with decFile(file_name, passphrase) as f:
    stuff = f.read()

pyaxo - an implementation of the Axolotl cryptographic ratchet protocol in python

I've written an implementation of the Axolotl cryptographic ratcheting protocol in python.

Overview

The Axolotl ratchet is a protocol (similar to OTR) that provides for perfect forward secrecy in (a)synchronous communications. It uses triple Diffie-Hellman for authentication and ECDHE for perfect forward secrecy. The protocol is lighter and more robust than the OTR protocol - providing better forward and future secrecy, as well as deniability.

The protocol was developed by Trevor Perrin and Moxie Marlinspike. Its chief use currently is in the Whisper Systems TextSecure SMS package.

A nice writeup of the protocol is on the Whisper Systems Blog. You can find the most recent specification of the protocol here.

Installation instructions

Install with sudo python setup.py install

If you have setuptools installed, the required python-gnupg package will be downloaded and installed automatically.

pyaxo also requires the curve25519-donna package for doing the ECDHE calculations. This package won't be installed automatically. It can be installed by:

 git clone https://github.com/agl/curve25519-donna
 cd curve25519-donna
 sudo python setup.py install

You may need some additional python modules as well. Check the imports list.

There are several examples showing usage. There are also encrypt_pipe() and decrypt_pipe() methods for use in certain applications. I haven't put together an example using them yet, but it should be straightforward. Note: the weechat-axolotl plugin linked below uses these pipe methods.

Bugs, etc. should be reported to the pyaxo github issues page.

Ideas for the future

It seems to me that Axolotl is essentially a drop-in replacement for OTR. Toward that end, I've also written a weechat script for secure private messaging using Axolotl. A utility for generating the required databases is also included. I also plan to convert encoDHer to use Axolotl as well.

All code, text and images are Copyright © 2013-2017 by David R. Andersen. All rights reserved unless otherwise specified.
This site is produced using the Haggis static site generator.