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()