We're hiring!

We're actively seeking developers and designers for our Detroit & Ann Arbor locations.

Getting Started with GNU Privacy Guard

This is part of a series on GNU Privacy Guard:

  1. Getting Started with GNU Privacy Guard (this post)
  2. Generating More Secure GPG Keys: Rationale
  3. Generating More Secure GPG Keys: A Step-by-Step Guide
  4. Using an OpenPGP Smartcard with GnuPG

Like many others, I have recently taken a more active interest in information security. In particular, I have taken a fresh look at GNU Privacy Guard (GnuPG or GPG). This popular open-source encryption tool offers users the ability to encrypt and sign data and communications using public key cryptography.

I’ve used GPG in the past, but now that I’ve read up on it a little more, I’d like to share some of what I’ve learned. This post won’t get into the relative merits of RSA, DSA, or ECC keys, or extra measures you can take to keep your private key secure. I hope to cover those things in more detail later.

This post is intended to serve as a brief introduction to GPG and should also help to clear up some confusing vocabulary to make further reading more fruitful.


Public Key Cryptography

Encryption

I will assume you already have some familiarity with the basic concepts of public key cryptography — that messages can be encrypted using one publicly-available key that can only be decrypted by another key, one kept secret and protected. This asymmetry is powerful, and is useful in many different contexts.

Authentication

Besides encryption, public key cryptography can be used in place of passwords for authentication. Using public/private keypairs for authentication means that a user can use one private key to gain access to many different servers or services. This is in contrast to (symmetric) passwords where sharing the same password with more than one site would be a major risk. This is one reason why I prefer key-based authentication for SSH, for example.

Signing

Another use for public-private keypairs is signing. Using a private key, a sender can “sign” a message, signifying that they originated or approved its exact contents. This allows a receiver to use the sender’s public key, verifying not only that the sender holds the corresponding private part, but also that the message hasn’t been tampered with — the message is bound to the key. Any change to the message would cause the signature to be invalid.

Certification

Similar to signing messages, keys can also be used to sign other keys. This capability can either be used to denote that you claim a set of keys or that you trust someone else has control of another key.

Three Types of “Keys”

Let’s begin honing our understanding by talking about one word: “key.” I have seen this word used to denote at least three distinct (but related) things.

In the first sense, people sometimes talk about the two keys — a “public key” and a “private key” — that go into a “keypair.” (This private key is also sometimes called a “secret key”).

In the second sense, people will sometimes refer to a keypair as a “key.”

        +------------------------------------------------------+
        |                        keypair                       |
        | +------------------------+ +------------------------+|
        | |                        | |                        ||
        | |        private         | |         public         ||
        | |                        | |                        ||
        | +------------------------+ +------------------------+|
        +------------------------------------------------------+

In a third sense, people will often use the word “key” to refer to an OpenPGP “key” containing a primary key (keypair) and zero or more subkeys (keypairs).

                 +--------------------------------------+
                 |           OpenPGP "key"              |
                 |                                      |
                 | +----------------------------------+ |
                 | | primary key                      | |
                 | | +----------------+-------------+ | |
                 | | |                |             | | |
                 | | +----------------+-------------+ | |
                 | +----------------------------------+ |
                 |                                      |
                 | +----------------------------------+ |
                 | | subkey                           | |
                 | | +----------------+--------------+| |
                 | | |                |              || |
                 | | +----------------+--------------+| |
                 | +----------------------------------+ |
                 |                                      |
                 | +----------------------------------+ |
                 | | subkey                           | |
                 | | +----------------+--------------+| |
                 | | |                |              || |
                 | | +----------------+--------------+| |
                 | +----------------------------------+ |
                 |  . . .                               |
                 | +---------+-----------+------------+ |
                 | |         |           |   other    | |
                 | | uids    | notations |  metadata  | |
                 | +---------+-----------+------------+ |
                 +--------------------------------------+

GPG Concepts

Building on these ideas, let’s look at how GPG works with keys. GPG works with keys in terms of keypairs (corresponding public and private parts). GPG also has a concept of a primary key (keypair) and subkeys (keypairs) that are bound together by signing the subkeys as belonging to the same set with the primary key.

Here’s an example (taken from the output of gpg --list-secret-keys):

sec   2048R/905D5761 2011-11-08 [expires: 2011-11-22]
uid                  Mike English (Temporary Key) <mike.english@example.com>
ssb   2048R/4AD85450 2011-11-08

Let’s go through what this means line by line.

sec   2048R/905D5761 2011-11-08 [expires: 2011-11-22]
  • sec – We have the secret (private) part of this primary key in our keyring.
  • 2048R – This is a 2048-bit RSA key.
  • 905D5761 – This the “KeyID,” the tail end of the key’s “fingerprint.”
  • 2011-11-08 – The creation date of this key.
  • [expires: 2011-11-22] – This key should no longer be used. It expired 2011-11-22.
uid                  Mike English (Temporary Key) <mike.english@example.com>
  • uid – What follows is a uid for this key (a key may have zero or more uids).
  • Mike English – The “Real Name”
  • (Temporary Key) – The “Comment”
  • <mike.english@example.com> – The e-mail address
ssb   2048R/4AD85450 2011-11-08
  • ssb – This is a subkey. We have the secret part in our keyring.
  • 2048R – This subkey is another 2048-bit RSA key.
  • 4AD85450 – The “KeyID” for this subkey, again derived from the key’s fingerprint.
  • 2011-11-08 – The creation date of this subkey.

In the above example, the primary key is labeled sec (meaning we have the “secret” part) and a subkey is labeled ssb. The uid is an identifier associated with the key for convenience.

As noted above, the term “key” can designate (at least) three different things here. We could be referring to one part (public or private) of an individual keypair. We could be referring to a keypair (since they are linked, they are sometimes referred to as one “key” as when we say “primary key” or “subkey”). We might also be referring to the primary key and all of its associated uids and subkeys (a key can have more than one uid or subkey).

Here’s another example (this one taken from the output of gpg --list-keys):

pub   2048D/00D026C4 2010-08-19 [expires: 2015-08-18]
uid                  GPGTools Project Team (Official OpenPGP Key) <gpgtools-org@lists.gpgtools.org>
uid                  GPGMail Project Team (Official OpenPGP Key) <gpgmail-devel@lists.gpgmail.org>
sub   2048g/DBCBE671 2010-08-19 [expires: 2015-08-18]

In this example we have only the public (pub) part of the primary key and one subkey (sub). This key also demonstrates the fact that multiple uids can be associated with the same key.

GPG Keyrings

When we generate our first key, we’ll see that GPG creates a new directory ~/.gnupg and several files:

  • ~/.gnupg/gpg.conf
  • ~/.gnupg/secring.gpg
  • ~/.gnupg/pubring.gpg

gpg.conf contains configuration info. The other two files are keyrings. GPG holds keys in “keyrings”. By default two files are used for this:

  • ~/.gnupg/secring.gpg holds the secret (private) parts of keys where we have them (our private keys)
  • ~/.gnupg/pubring.gpg holds the public parts of keys (ours and others’)

gpg -k is short for gpg --list-keys which will show public keys we have in our keyring.

gpg -K is short for gpg --list-secret-keys which will show us secret keys we have in our keyring.

$ gpg -k
/Users/english/.gnupg/pubring.gpg
---------------------------------
pub   2048R/810681E9 2013-09-19
uid                  Mike English (Junk key for blogpost) <mike.english@example.com>
sub   2048R/9857CF87 2013-09-19
 
$ gpg -K
/Users/english/.gnupg/secring.gpg
---------------------------------
sec   2048R/810681E9 2013-09-19
uid                  Mike English (Junk key for blogpost) <mike.english@example.com>
ssb   2048R/9857CF87 2013-09-19

Example / Getting Started

1. Installing GPG

I recommend skipping the GUI tools for now. It’s worth the effort to understand how GPG works so that you can make an informed decision about choosing wrappers that may provide added convenience. Using the command line interface will allow you to develop a better understanding of GPG’s operational model.

On a Mac, we can install gpg via Homebrew:

$ brew install gpg
==> Downloading ftp://ftp.gnupg.org/gcrypt/gnupg/gnupg-1.4.13.tar.bz2
Already downloaded: /Library/Caches/Homebrew/gnupg-1.4.13.tar.bz2
==> ./configure --prefix=/usr/local/Cellar/gnupg/1.4.13 --disable-asm
==> make CFLAGS= -std=gnu89 -fheinous-gnu-extensions
==> make check
==> make install
  /usr/local/Cellar/gnupg/1.4.13: 54 files, 5.2M, built in 51 seconds
$ gpg --version
gpg (GnuPG) 1.4.13
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
 
Home: ~/.gnupg
Supported algorithms:
Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

2. Generating a New Key

Here’s how to generate a new key, accepting all the defaults:

$ gpg --gen-key
gpg (GnuPG) 1.4.13; Copyright (C) 2012 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
 
gpg: directory `/Users/english/.gnupg' created
gpg: new configuration file `/Users/english/.gnupg/gpg.conf' created
gpg: WARNING: options in `/Users/english/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/Users/english/.gnupg/secring.gpg' created
gpg: keyring `/Users/english/.gnupg/pubring.gpg' created
Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
Requested keysize is 2048 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y
 
You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"
 
Real name: Mike English
Email address: mike.english@example.com
Comment: Junk key for blogpost
You selected this USER-ID:
    "Mike English (Junk key for blogpost) <mike.english@example.com>"
 
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.
 
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
+++++
............+++++
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
........+++++
......+++++
gpg: /Users/english/.gnupg/trustdb.gpg: trustdb created
gpg: key 810681E9 marked as ultimately trusted
public and secret key created and signed.
 
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   2048R/810681E9 2013-09-19
      Key fingerprint = 4ADF DB89 FC3D CC41 7CC1  FFB4 1138 9CAA 8106 81E9
uid                  Mike English (Junk key for blogpost) <mike.english@example.com>
sub   2048R/9857CF87 2013-09-19
 
$

3. Signing

First something to sign:

$ cat > important_message.txt
This is an important message.
You will want to know that it is really from me.
You will also want to know that it has arrived intact, without any tampering.
By signing it, I can assure you (so long as you already trust that I control the private key I will use).
 
$

Then we can sign it:

$ gpg --clearsign important_message.txt
 
You need a passphrase to unlock the secret key for
user: "Mike English (Junk key for blogpost) <mike.english@example.com>"
2048-bit RSA key, ID 810681E9, created 2013-09-19
 
$ cat important_message.txt.asc
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
 
This is an important message.
You will want to know that it is really from me.
You will also want to know that it has arrived intact, without any tampering.
By signing it, I can assure you (so long as you already trust that I control the private key I will use).
 
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.13 (Darwin)
 
iQEcBAEBAgAGBQJSO73pAAoJEBE4nKqBBoHpB94H/3p5QvHi7kkVxQ6a936r+Weo
Jiy+blzVsMRCQzhjtQ1dm/VZIA13gGSSatQDfPfLTwDbQ3T261W5kr3+S3AoeBEr
Kf1taidyZEUlr8WXoFERJb2TefzLwL4uJTsYTh32pRjX64sc02ckyV334/o4KleU
Gkxv6o3UqmsH5bj5S4wEd/8TvXvizZyhy42JdKOxFoFz47flKLkJy7wWwmIhRu/w
SkNQVlSZzUBcueJmOWFY5nqW96glyiRsh4Yjg07Y5Qt257Lqkt3s+tKYkR3bF3QM
kVWwzidQAllajP+a0JUgWzmsMocVQvd6Gm3lO8CpxlIpetkK1uq1NaCIcCR9RIQ=
=v1O6
-----END PGP SIGNATURE-----
$

4. Encryption

Something to encrypt:

$ cat > secret_message.txt
This is a secret message.
It is important that you be the only one to read it.
I will encrypt this message with your public key so that you can decrypt it with your private key.

Choose a recipient from our public keyring (In this case, ourselves):

$ gpg --list-keys
/Users/english/.gnupg/pubring.gpg
---------------------------------
pub   2048R/810681E9 2013-09-19
uid                  Mike English (Junk key for blogpost) <mike.english@example.com>
sub   2048R/9857CF87 2013-09-19

And then encrypt the message:

$ gpg -r mike.english@example.com --armor --encrypt secret_message.txt
$ cat secret_message.txt.asc
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.4.13 (Darwin)
 
hQEMAzCAW/+YV8+HAQf9GoxHtvWMtgSdRxfg+0p1foglWzbIpy2FYOziVyivmCAq
1Q/rH1FbmbqXYjwadwD03KkSsg5fTo+BpaZs6THxO9ADRj+kYp+wmJE4c7J/QXY7
TcvURbo/H9lv9CVRRrL8ovv6S1O3RHsvMF7CU7AtYoXqCmOLrDM30Du/j/kanhWF
2H9znYyfWnhJ5d7JRQ95n9ZmwU+OtloWPay3pFM++40mbSEjNvUrwDhqK+GKvoit
Te3EBtLyonXwwel7coWIbL2Bz1083DzBL0b5D4nyGNEIDL3SEsnfMIHa944LZXIu
OWdrioWr2ivMhR4fuV1fQuTImn710Fpb8DS8b5TRtNK/AUHrxPCXeV4WycI8nbwa
KzsdO/zgjM1yvTEJUR26luEgYbd9Bcip/0FOWab18GRJMgdC4keXGPRds9Gtip5a
2QWW7KDXfYts+ODVi19juJp6kSz9D/TwMtX1gq+5J1+OGvY7FMNZQiiuxD+VXpgP
B0GkJS2dmIrz+81hj7RMq1+iziyfQ3rooNW9r+Mh/B5W00I8/VKo/A65i4P1WLgJ
pBvg6I30su8p8Y8RBa3EEsAEYAcpVUGe1s3lU1N+KM4=
=gyNk
-----END PGP MESSAGE-----
$

5. Decryption

Since we have the matching private key…

$ gpg -d secret_message.txt.asc
 
You need a passphrase to unlock the secret key for
user: "Mike English (Junk key for blogpost) <mike.english@example.com>"
2048-bit RSA key, ID 9857CF87, created 2013-09-19 (main key ID 810681E9)
 
gpg: encrypted with 2048-bit RSA key, ID 9857CF87, created 2013-09-19
      "Mike English (Junk key for blogpost) <mike.english@example.com>"
This is a secret message.
It is important that you be the only one to read it.
I will encrypt this message with your public key so that you can decrypt it with your private key.

…we are able to decrypt this secret message:

$ gpg -d secret_message.txt.asc
 
You need a passphrase to unlock the secret key for
user: "Mike English (Junk key for blogpost) <mike.english@example.com>"
2048-bit RSA key, ID 9857CF87, created 2013-09-19 (main key ID 810681E9)
 
gpg: encrypted with 2048-bit RSA key, ID 9857CF87, created 2013-09-19
      "Mike English (Junk key for blogpost) <mike.english@example.com>"
This is a secret message.
It is important that you be the only one to read it.
I will encrypt this message with your public key so that you can decrypt it with your private key.
 
$

Full Demo

If you’d prefer to spend six minutes watching the above example typed out in real time, you’re in luck!

I’ve uploaded a recording to ascii.io.

Further Reading


This is part of a series on GNU Privacy Guard:

  1. Getting Started with GNU Privacy Guard (this post)
  2. Generating More Secure GPG Keys: Rationale
  3. Generating More Secure GPG Keys: A Step-by-Step Guide
  4. Using a GPG Key with a SmartCard (coming 12/2013)

 

Mike English (25 Posts)

Professional Problem Solver

This entry was posted in Extracurricular Activities and tagged . Bookmark the permalink. Both comments and trackbacks are currently closed.

2 Comments

  1. Posted October 2, 2013 at 1:43 pm

    Hey Mike, great article! We included it in our resource round up- http://www.wiredtree.com/blog/monthly-round-up-septembers-best-web-designdevelopment-cms-security-content/.

    Cheers!

    • Mike English
      Posted October 2, 2013 at 3:19 pm

      Thanks Nicky, I appreciate it. I’ll be writing more about how to use GnuPG soon!