Heading image for post: Encryption with gpg, a story (really, a tutorial)

Encryption with gpg, a story (really, a tutorial)

Profile picture of Chris Erin

GPG is a compatible replacement of PGP. That, in and of itself, is confusing.

That each acronym is sufficiently obtuse on its own is enough to prompt a less privacy minded developer to give up. GPG stands for Gnu Privacy Guard and PGP stands for Pretty Good Privacy. Pretty Good Privacy came first and prompted the government to prosecute the creator, Phil Zimmerman, for exporting munitions illegally. He published the code in a book, and then he was exporting a book not munitions.

The first thing to understand about gpg is that it is not like openssl. openssl takes inputs and delivers outputs and maintains no state inbetween requests. gpg, on the other hand, functions as a key server along with encrypting, decrypting and key generation. It runs in the background, a daemon, and manages your private keys and the public keys of others. It is a program intended to encrypt emails and therefore uses option names like recipient to indicate which public key to encrypt a message with.

Its a key manager

When you understand gpg as key manager before you understand it as an encryption tool then it is easier to learn how to use. Therefore, you should install the program with brew or apt-get and then use it to list all the keys that its managing.

> gpg --list-keys
gpg: directory `/Users/chriserin/.gnupg' created
gpg: new configuration file `/Users/chriserin/.gnupg/gpg.conf' created
gpg: WARNING: options in `/Users/chriserin/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/Users/chriserin/.gnupg/pubring.gpg' created
gpg: /Users/chriserin/.gnupg/trustdb.gpg: trustdb created

It has created files and issued a warning. It needed to have the resources to manage your keys and now it has them. If we list keys again:

> gpg --list-keys

Nothing. Great. Lets get started. Here's a public key that you can manage.

Version: GnuPG v2


You can copy this public key to a file named chriserin.pub and import it:

> gpg --import chriserin.pub

Now when you run list-keys you can see a key is listed:

> gpg --list-keys
pub   2048R/7C731F14 2017-03-30
uid       [ unknown] Chris Erin (Be Kind To Others) <chris.erin@hashrocket.com>
sub   2048R/1CC31A83 2017-03-30

Encrypting messages

Now we have a key to encrypt with. Please encrypt a message for me that only I can read.

> echo "a really interesting message" | gpg --armor --encrypt --recipient chris.erin@hashrocket.com

Now, if you send me the output of that message, only I will be able to read it.

There is an interesting option there, --armor. The man pages describe --armor as:

Create ASCII armored output

Its something you need if you plan on transmiting this message in ascii formats like email.

Decrypting messages

When I get your message I'll be curious and want to decrypt it. Decrypting is a little bit more envolved then encrypting but still relatively easy.

First, I need to make sure that my private key is managed.

> gpg --list-secret-keys

Nothing! I'll need to import it.

> gpg --import chriserin.priv
> gpg --list-secret-keys
sec   2048R/7C731F14 2017-03-30
uid                  Chris Erin (Be Kind To Others) <chris.erin@hashrocket.com>
ssb   2048R/1CC31A83 2017-03-30

Now lets decrypt the message. What's unique about the decryption process on my end is that I need to enter a passphrase. I will be prompted to enter this passphrase when the below command is run.

> gpg --output interesting.txt --no-tty message.gpg

I should now have a file that has the content

a really interesting message

Creating a key pair

Necessary if you expect to receive encrypted messages is a key pair. A public key that you can distribute on the internet as freely as you see fit and a private key which should be guarded and protected.

gpg provides a command option for this:

> gpg --gen-key

Which asks you for a set of information including your name, email, an optional comment, and a passphrase. As we've seen while encrypting a message, the email is the unique identifier by which the user specifies a recipient and through which the gpg program identifies which public key to use for encryption.

One tricky thing about this key generation on linux is that when generating the key itself the program complained about not having enough entropy and hung until the entropy requirement was met. When googling I discovered that this was a common complaint and most often solved by installing the rng-tools with apt-get as described here.

If you are able to create a key successfully it should be in your list of keys, both the secret list and the public list:

> gpg --list-keys
> gpg --list-secrety-keys

You'll want to have a public key to distribute which you can obtain with:

> gpg --export -a "Chris Erin" > chriserin.pub

And potentially you'll want to move the private key to a different location. It can be exported with:

> gpg --export-secret-keys -a "Chris Erin" > chriserin.priv

Finally, knowing that you can manage keys with gpg you are probably assuming that they are deleteable. Delete them with:

> gpg --delete-secret-keys chris.erin@hashrocket.com
> gpg --delete-keys chris.erin@hashrocket.com

Now you're back where you started. Happy encrypting!

More posts about Encryption