Python modules you should know: PyGPGME

May 23, 2012 at 07:40 AM | categories: Python, PyMYSK, Howto | View Comments

Next in our series of Python modules you should know is PyGPGME. This package lets you sign, verify, encrypt and decrypt messages using the OpenPGP format. It is built on top of the GNU Privacy Guard and the GPGME library.

Home page

Use

PyGPGME is a Python module that lets you sign, verify, encrypt and decrypt messages using the OpenPGP format.

Installation

You need the GPGME library and header files installed to successfully install PyGPGME

pip install PyGPGME

Usage

The documentation for this package is almost non existent i hope my examples will be able to help at least with getting users started

Creating a key

This is similar to running the following command:

gpg --gen-key
import os
import gpgme

key_params = """
<GnupgKeyParms format="internal">
Key-Type: RSA
Key-Length: 2048
Name-Real: Jaja of Opobo
Name-Email: jaja@example.com
Expire-Date: 0
Passphrase: secret
</GnupgKeyParms>
"""

# create custom gpg directory
gpghome = os.path.expanduser('~/gpghome')
if not os.path.exists(gpghome):
    os.mkdir(gpghome, 0700)

# set the environment to custom gpg directory
os.environ['GNUPGHOME'] = gpghome
# create a blank configuration file
with open(os.path.join(gpghome, 'gpg.conf'), 'wv') as handle:
    handle.write('')

# create a context
ctx = gpgme.Context()
# create the key using key_params
result = ctx.genkey(key_params)
# get the key
key = ctx.get_key(result.fpr, True)
[uid] = key.uids
# print key name and email
print uid.name, uid.email

Exporting a key

This is similar to running the following command:

gpg --export [UID]
import os
import gpgme
from io import BytesIO

# set the environment to custom gpg directory
gpghome = os.path.expanduser('~/gpghome')
os.environ['GNUPGHOME'] = gpghome

# create a context
ctx = gpgme.Context()
ctx.armor = True
keydata = BytesIO()
[key] = ctx.keylist()
ctx.export(key.subkeys[0].keyid, keydata)
print keydata.getvalue()

Importing a key

This is similar to running the following command:

gpg --import [Filename]
import os
import gpgme
import urllib2

# set the environment to custom gpg directory
gpghome = os.path.expanduser('~/gpghome')
os.environ['GNUPGHOME'] = gpghome

# create a context
ctx = gpgme.Context()
# Download a public key
handle = urllib2.urlopen('http://repo.baruwa.org/RPM-GPG-KEY-BARUWA')
# Import the key
_ = ctx.import_(handle)
# Get key and print out keyID
key = ctx.get_key('4BA17AC7')
print "Imported key ID: ", key.uids[0].uid

Delete a key

This is similar to running the following command:

gpg --delete-key UID
import os
import gpgme

# set the environment to custom gpg directory
gpghome = os.path.expanduser('~/gpghome')
os.environ['GNUPGHOME'] = gpghome

# create a context
ctx = gpgme.Context()
# Get the public key we just imported
key = ctx.get_key('4BA17AC7')
# Delete the key
ctx.delete(key)

Sign and verify text

This is similar to running the following commands:

gpg -s (or --sign) [Data]
gpg [--verify] [Data]
import os
import gpgme
from io import BytesIO

# set the environment to custom gpg directory
gpghome = os.path.expanduser('~/gpghome')
os.environ['GNUPGHOME'] = gpghome
# allow our passphrase callback to work
del os.environ['GPG_AGENT_INFO']

# passphrase callback function
def passphrase_cb(uid_hint, passphrase_info, prev_was_bad, fd):
    "pass phrase callback"
    os.write(fd, b'secret\\n')

# create a context
ctx = gpgme.Context()
ctx.armor = True
[key] = ctx.keylist()
ctx.signers = [key]
ctx.passphrase_cb = passphrase_cb

# sign the data
plaintext = BytesIO(b'Text to be signed\\n')
signature = BytesIO()
signed = ctx.sign(plaintext, signature, gpgme.SIG_MODE_DETACH)

# rewind files
_ = signature.seek(0)
_ = plaintext.seek(0)

# Verify signature
sigs = ctx.verify(signature, plaintext, None)
if sigs[0].fpr == key.subkeys[0].fpr:
    print "Signature verified"
    print sigs[0].fpr, key.subkeys[0].fpr
else:
    print "Signature verification failed"

Encrypt and Decrypt text

This is similar to running the following commands:

gpg -e Recipient [Data]
gpg [-d] [Data]
import os
import gpgme
from io import BytesIO

# set the environment to custom gpg directory
gpghome = os.path.expanduser('~/gpghome')
os.environ['GNUPGHOME'] = gpghome
# allow our passphrase callback to work
del os.environ['GPG_AGENT_INFO']

recipient_params = """
<GnupgKeyParms format="internal">
Key-Type: RSA
Key-Length: 2048
Name-Real: Nana of itsikiri
Name-Email: nana@example.com
Expire-Date: 0
Passphrase: secret
</GnupgKeyParms>
"""

# passphrase callback function
def passphrase_cb(uid_hint, passphrase_info, prev_was_bad, fd):
    "pass phrase callback"
    os.write(fd, b'secret\\n')

# create a context
ctx = gpgme.Context()
ctx.armor = True
# create a recipient's key
result = ctx.genkey(recipient_params)
recipient = ctx.get_key(result.fpr, True)

plaintext = BytesIO(b'Very Secret text\\n')
ciphertext = BytesIO()
ctx.encrypt([recipient], gpgme.ENCRYPT_ALWAYS_TRUST, plaintext, ciphertext)

# rewind files
_ = ciphertext.seek(0)
_ = plaintext = BytesIO()
ctx.passphrase_cb = passphrase_cb
ctx.decrypt(ciphertext, plaintext)
print "The decrypted text is: ", plaintext.getvalue()

List keys

This is similar to running the following command:

gpg --list-keys
import os
import gpgme

# set the environment to custom gpg directory
gpghome = os.path.expanduser('~/gpghome')
os.environ['GNUPGHOME'] = gpghome

# create a context
ctx = gpgme.Context()
# iterate key list
for key in ctx.keylist():
    for uid in key.uids:
        print uid.uid

List secret keys

This is similar to running the following command:

gpg --list-secret-keys
import os
import gpgme

# set the environment to custom gpg directory
gpghome = os.path.expanduser('~/gpghome')
os.environ['GNUPGHOME'] = gpghome

# create a context
ctx = gpgme.Context()
# iterate secret key list
for key in ctx.keylist(None, True):
    for uid in key.uids:
        print uid.uid

And there is more.

For more GPG operations you can perform look at the API

import gpgme
help(gpgme)

blog comments powered by Disqus