5/10/2016 - 5:46 PM

Basic GPGME ruby gem usage

Basic GPGME ruby gem usage

Basic GPGME Ruby Gem Usage

I just found this API ridiculously confusing to use, and maybe I just suck, but I don't want to figure it out again, so I'm writing it down here

Establish a gpg home dir if desired

Optional, but if you have an established gpg home dir that you want to use or you don't want it chosen for you

GPGME::Engine.home_dir = "/some/dir" # e.g. env['GNUPG_HOME']

Note If you already have keys imported in that home dir, you can skip this part:

Import a key

Only need to do once for each key, but repeated imports are ok too.

A very basic explanation of keys in case you're not familiar:

  • Private keys
    • You need to import at least 1 private key to decrypt anything asymmetrically encrypted
    • You also need the private key in order to cryptographically "sign" something
    • When you use a private key for one of these operations you'll usually need to provide a password or a password callback function (hook, agent etc) in order to get access to the private key
  • Public keys
    • You'll need 1 public key for each person or account for which you want to encrypt
    • You'll also need these keys to verify they have cryptographically "signed" something
    • If you aren't using some sort of chain of trust (web of trust) and/or the keys aren't signed by anyone you already trust, you'll need to specify always_trust :true
### The keys are "saved" in your GPGME::Engine.home_dir which is why they don't really persist in ruby land"keyfile", 'rb') do |key_file|
    {armor: true, keylist_mode: GPGME::KEYLIST_MODE_LOCAL}

Create a basic crypto object

It will inherit the keys assuming you don't change home_dir again) Note You can specify options now and/or when you call additional methods or both

list of crypto options

additional ctx options available

crypto ={always_trust: true})

Note Most of the GPGME methods return a GPGME::Data object which can be read just like a typical IO object, but remember to seek(0) to return to the beginning if nec.


cipher_text = crypto.encrypt(
  "test text",
  {recipients: ''}
  # or recipients: ['', '']
# recipients: could have been specified w/the crypto object or when calling encrypt
# same goes for always_trust:


clear_text = crypto.decrypt(
  {keylist_mode: GPGME::KEYLIST_MODE_LOCAL, password: 'blah'}

Note If you previously called etc you'll need to first call 0

Read the output
clear_text.see(0) # optional