Approaching OpenPGP

Despite having worked in an information security lab in undergrad, I’ve generally been pretty casual about my own security. I protect my machines from direct attacks and monitor their logs, but my communications are almost always in cleartext and are typically stored on remote servers over which I have no control. When I’ve thought about it, I’ve felt somewhat remiss, but convenience and the number of other things to which I need to devote time have won out over proper security. Recent revelations have gotten me thinking about these matters again, though, and I decided it was time to set up an OpenPGP key.

Very briefly: Pretty Good Privacy (PGP) was created as a decentralized way of providing public-key cryptography in which users have control over what it takes to convince them to trust another user. OpenPGP is a standard based on PGP proper. The most prominent and perhaps the only free implementation of the OpenPGP standard is GNU Privacy Guard (GPG), and this is the software I have been using. Without going into the theory behind it, the important feature of public-key cryptography is that it allows people to send you messages that only you can read (encryption), and to verify that a message you’ve sent was actually sent by you (signatures).

This post will demonstrate how to create a key on an encrypted device (or encrypted file), how to generate subkeys, and how to publish your public keys. I’ll be assuming the use of Linux, but I will give suggestions for Windows or OS X users where I have any.

While this post was going to include how to use GnuPG with Thunderbird, the length here demands a reduction in scope. A post about everyday use should follow shortly.

Creating a Secure Device

Although we will later be publishing our public keys, private keys should be guarded with some degree of paranoia. In particular, you want to protect your master key from ever falling into the hands of anybody that is not actually you. To this end, I recommend getting a USB key. It doesn’t need to be large, but it needs to be one you can dedicate to this purpose. If this does not appeal to you, feel free to proceed to the next section; all of the same commands will work, regardless of whether you follow these steps. If your USB key registers as /dev/sdb, type the following line into your terminal:


If it registers otherwise, make the appropriate adjustment. If you do not have a key handy, you can create a 100MB image as follows:

dd bs=10M count=10 if=/dev/zero of=$DEV

The steps from here on out are agnostic to what type of device you use. Windows and OS X users may wish to use TrueCrypt — as may Linux users, for that matter — but I will be using LUKS, which I have used before and am confident in.

sudo cryptsetup --verbose --verify-passphrase luksFormat $DEV

You will be asked to enter the same passphrase twice. The usual concerns about passwords apply here. We can now decrypt the device using that passphrase:

sudo cryptsetup luksOpen $DEV gpgdev

This creates a mapped device called /dev/mapper/gpgdev. This device needs a filesystem. I chose to use ext2, as no fancy features are needed, but this is probably the least important decision, so I’m not going to belabor it. If you prefer another filesystem, modify the first line of the following block. Otherwise:

sudo mkfs.ext2 /dev/mapper/gpgdev
sudo mkdir -p /mnt/gpgdev
sudo mount -t ext2 -o rw /dev/mapper/gpgdev /mnt/gpgdev
sudo chmod -R go= /mnt/gpgdev
sudo chown -R `whoami`: /mnt/gpgdev

We now have a secure device. Finally, we’re going to bind this filesystem to the usual GnuPG directory so that we can work as normal.

mkdir -p ~/.gnupg
sudo mount --bind /mnt/gpgdev ~/.gnupg

Creating a Master Key

gpg2 --gen-key

This command instantly creates ~/.gnupg/pubring.gpg and ~/.gnupg/secring.gpg. An interactive wizard is presented

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?

The first two options are for signing (DSA or RSA) and encrypting (RSA or ElGamal) keys, the latter allow you simply to choose the signing key without creating an encrypting key. We’ll create an encrypting subkey, later, so we’re going to choose (4).

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)

2048 bits is fine by basically everybody’s standards, but the only penalty for going 4096 is that it takes a little longer to generate your key. Given that we’re about to say this key never expires, why not go for 4096?

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)

Hit enter, and don’t expire this key. After a key expires, you’ll need to rebuild your reputation from scratch, and part of the reason for the paranoia is to avoid events that would cause you to need to begin again. Subkeys may expire or be revoked without the same reconstruction process, and so we can be a bit more casual with them.

Key does not expire at all
Is this correct? (y/N)


GnuPG needs to construct a user ID to identify your key.

Real name: 
Email address: 

This is where you get to decide how to present yourself. I can’t tell you how to do this.

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?

O, when you’re ready. Then it will be time to enter a passphrase. Again, standard passphrase considerations apply. You will need to type this whenever you need access to your private keys. That said, it should not be the same as the passphrase on your device (or device image). Generating the key will take time. Eventually you will see something like the following:

gpg: key AB61566E marked as ultimately trusted
public and secret key created and signed.

Using your own key ID, let’s normalize the rest of the process with:



gpg2 --expert --edit-key $KEY_ID

Now we want to create signing and encryption keys. Optionally, we can create an authentication key. I figure we might as well go ahead and do one of each. Use the addkey command at the gpg> prompt. You’ll be asked to enter your passphrase from earlier.

Please select what kind of key you want:
   (3) DSA (sign only)
   (4) RSA (sign only)
   (5) Elgamal (encrypt only)
   (6) RSA (encrypt only)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
Your selection?

We’re going to do this three times: for sign (4), for crypt (6), and for authenticate (8). The following occurs for the (8):

Possible actions for a RSA key: Sign Encrypt Authenticate 
Current allowed actions: Sign Encrypt 

   (S) Toggle the sign capability
   (E) Toggle the encrypt capability
   (A) Toggle the authenticate capability
   (Q) Finished

Your selection?

You can only perform one action at a time. To remove the sign and encrypt capabilities and add the authenticate capability, type S<ENTER>E<ENTER>A<ENTER>Q<ENTER>. This brings us to the same place that (4) and (6) would:

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)

In this case, I can’t think of a stretchily paranoid reason to want more than 2048 bites, so I would recommend simply hitting enter.

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)

Here I’ll recommend expiring after 1y.

After all three keys are generated, you should see something like:

pub  4096R/AB61566E  created: 2013-07-01  expires: never       usage: SC  
                     trust: ultimate      validity: ultimate
sub  2048R/25DEDEB3  created: 2013-07-01  expires: 2014-07-01  usage: S   
sub  2048R/C23FB19B  created: 2013-07-01  expires: 2014-07-01  usage: E   
sub  2048R/B25F4F6D  created: 2013-07-01  expires: 2014-07-01  usage: A   
[ultimate] (1). <UID>

Let’s hold on to these IDs like so:



That <UID> may not be your only way of representing yourself. Assuming you have multiple email addresses, nicknames, aliases that you want to be identified as being the same person, you can add new UIDs with the following command:


There’s no penalty to adding many UIDs, but, if you’re going to add a UID, you should add it now. UIDs get signed by others, so delaying can mean a mismatch between identities you claim and identities others trust.


The point of public keys is to share them as far and wide as possible. Key servers have been set up that allow users to publish their own keys, as well as their signatures of other people’s keys or the revocation of their own. To publish your key, use the following command:

gpg2 --send-keys $KEY_ID

Note, however, that once a key is published, it cannot be unpublished, but merely revoked.

Emergency Revocation Certificate

While you have your master key is a good time to create a revocation certificate. This is a certificate that invalidates your key, and would be good to use if you forget your passphrase or have any reason to believe that your master key has been compromised.

gpg2 --output ~/.gnupg/$KEY_ID-revoke.asc --gen-revoke $KEY_ID

This should be protected almost as strongly as your master key. I’ve placed it on the same device, but you may want to consider finding another safe place for it.

Protecting the Master Key

If you did as I suggested and constructed your keys on an encrypted filesystem, it’s now time to split the public keys and subkeys from the master private key.

gpg2 --export $KEY_ID > /mnt/gpgdev/pubkeys
gpg2 --export-secret-subkeys $SUBKEY1! $SUBKEY2! $SUBKEY3! > /mnt/gpgdev/subkeys
sudo umount ~/.gnupg
gpg2 --import /mnt/gpgdev/pubkeys /mnt/gpgdev/subkeys
sudo umount /mnt/gpgdev
sudo cryptsetup luksClose gpgdev

In your unencrypted GnuPG directory, your private subkeys and all of your public keys are available. Your encrypted device still contains your full keyring, so when you need it to sign other people’s keys or create or revoke subkeys, you can simply reload it. However, your trust database was hidden along with your master key, so you need to run:

gpg2 --edit-key $KEY_ID

On the prompt, type trust.

Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision?

5 is more or less reserved for yourself, so go ahead and trust your key ultimately.


That’s about it. We now have created a master key as secure as we reasonably can, we have subkeys for everyday use, we have published our keys, and prepared for the worst. In future posts, we can get to actually encrypting and signing on an everyday basis.


The following pages have been immensely helpful in my exploration of GnuPG, presented in no particular order:

One thought on “Approaching OpenPGP

  1. Pingback: SSH Authentication with OpenPGP | Chris Johnson

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s