Encryption and Identity Verification using the GNU Privacy Guard (GnuPG)

GnuPG (GNU Privacy Guard) is a tool for creating key-pairs, used for encrypting and signing messages. It therefore provides a means to guarantee a your identity online and protect sensitive information.

A key-pair is a mechanism for asymmetric encryption. It consists of a private key and a public key. The public key is shared and is used by others to encrypt messages intended specifically for you, or to verify messages signed by you. In contrast, only the private key can be used to decrypt messages encrypted using the public key, and only the private key is used to sign messages. The private key must therefore be kept secret by the owner; if this key is stolen the thief can read encrypted messages sent to you and impersonate you online.

In the modern world with portable devices, such as laptops, keeping your key there can be risky. If the laptop is stolen, so is the key and potentially your identity online. However, two mechanisms can be used to help secure your key:

  • A passphrase on the key
  • Use of sub-keys

The passphrase is used to encrypt the key (using symmetric encryption). If the key is physically stolen, the thief still needs to know the passphrase to use the key. This passphrase should therefore be as strong as possible. Sub-keys can be used to limit the damage if a private key is stolen (e.g. on a laptop). They can be used in every-day circumstances for encrypting and signing messages, but can be revoked without damaging the reputation of the master key. The master key should therefore be kept very safe.

If you have multiple identities, i.e. email addresses, you can create a master key for each, or a single key can be associated with multiple user IDs. This choice depends entirely on the roles of these different identities.

Note: We will assume we have GnuPG version 2.1 or later available

Preparing to use GnuPG

On Debian systems, install the gnupg2 package.

Generating entropy can also be challenging. To help this, the hardware random number generator can be used. On Debian install the package rng-tools. Then run the rng daemon using ‘rngd -r /dev/urandom’ as root.

We create the file $HOME/.gnupg/gpg.conf with some options as suggested here:

cat << EOT >> $HOME/.gnupg/gpg.conf
# when outputting certificates, view user IDs distinctly from keys:
# long keyids are more collision-resistant than short keyids (it's 
# trivial to make a key with any desired short keyid)
keyid-format 0xlong
# when multiple digests are supported by all recipients, choose the 
# strongest one:
personal-digest-preferences SHA512 SHA384 SHA256 SHA224
# preferences chosen for new keys should prioritize stronger algorithms:
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 BZIP2 ZLIB ZIP Uncompressed
# You should always know at a glance which User IDs gpg thinks are 
# legitimately bound to the keys in your keyring:
verify-options show-uid-validity
list-options show-uid-validity
# when making an OpenPGP certification, use a stronger digest than 
# the default SHA1:
cert-digest-algo SHA256
# prevent version string from appearing in your signatures/public keys

Creating the master key

To create the master key run

gpg2 --full-gen-key

It will interactively prompt you for information. Choose

  • RSA and RSA (default) as the key type
  • 4096 is the key size to make it virtually impossible to crack using modern computers
  • 0 for the expiry, so that the master key does not expire

Confirm this is correct and then enter your real name and the email address to use as the identity.

Finally, enter a strong passphrase. As for all strong passphrases, make sure it is as long as practically possible. Avoid (combinations of) dictionary words, or their permutations.

After a short while (hopefully a few seconds with rngd), the key-pair will be generated.

Listing keys

There are two keyrings: public and private. The public keyring holds your own public keys as well as those of people you know and trust. The private keyring holds all your private keys. The keys in each can be listed using

$ gpg2 --list-keys [name]
$ gpg2 --list-secret-keys [name]

respectively. The optional [name] argument can be used to search for specific keys. The output might look something like the following:

$ gpg2 --list-keys
pub   rsa4096/0xC5D5DB322D019E3E 2016-09-03 [SC]
uid                   [ultimate] Your Name <user@domain>
sub   rsa4096/0x3569358E7B3F5D41 2016-09-03 [E]

The string 0xC5D5DB322D019E3E is the key-id.

Creating a sub-keys with GnuPG

When creating a master key above, we actually create two keys:

  • A master signing key
  • An encryption subkey

This can be seen when we use gpg to edit our key:

$ gpg --edit-key key-id

Initially, we see something like this:

sec  rsa4096/0xC5D5DB322D019E3E
     created: 2016-09-03  expires: never       usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa4096/0x3569358E7B3F5D41
     created: 2016-09-03  expires: never       usage: E   
[ultimate] (1). Your Name <user@domain>

Here we see we have a master key (indicated by sec), which does not expire and is used for signing (S) and certification (C). There is also a sub-key (ssb) used for encryption (E).

We now create an additional sub-key for every-day signing:

gpg> addkey

After entering your passphrase to unlock the master key, you will be prompted for the key type of the sub-key. We want RSA (sign only). Again, choose 4096 as the key size. It is a good idea to make this sub-key expire, since it is trivial to extend the expiry date and provides some safety if the private key is lost and you do not have access to a revokation certificate.

At the end, we see updated information on our key, now with our new signing sub key:

sec  rsa4096/0xC5D5DB322D019E3E
     created: 2016-09-03  expires: never       usage: SC  
     trust: ultimate      validity: ultimate
ssb  rsa4096/0x3569358E7B3F5D41
     created: 2016-09-03  expires: never       usage: E   
ssb  rsa4096/0x471A909DF2DE8245
     created: 2016-09-03  expires: 2017-09-03  usage: S   
[ultimate] (1). Your Name <user@domain>

Finally, save the key:

gpg> save

Removing a subkey

If you want to remove a sub-key, you should first select it using the key command, and then run delkey:

gpg> key 0x471A909DF2DE8245
gpg> delkey

If you have already shared your sub-key with others, you should revoke it to avoid people using it to send you messages you cannot decrypt.

Changing the expiry of a key

gpg2 --edit-key 0x471A909DF2DE8245

Then select the key and change the expiry, following the prompt.

gpg> key 0x471A909DF2DE8245
gpg> expire
gpg> save

Removing the master key

Now we have a sub-keys for both signing and encryption, we wish to secure our master key.

First we make a backup of our .gnupg directory and store it away in a safe place. Ideally, there would be multiple copies on an encrypted USB disks, stored in a number of safe places.

Since we are using GnuPG v2, all our keys are stored in $HOME/.gnupg/private-keys-v1.d. We first identify which is the master key:

$ gpg2 --with-keygrip --list-secret-keys
sec   rsa4096/0xC5D5DB322D019E3E 2016-09-03 [SC]
      Keygrip = 4CE46814D2CD6D5D56D6E38B39FE725630FC4276
uid                   [ultimate] Your Name <user@domain>
ssb   rsa4096/0x3569358E7B3F5D41 2016-09-03 [E]
      Keygrip = 31AA6E47711CE68C0D8046A4C27780739BEF71BD
ssb   rsa4096/0x471A909DF2DE8245 2016-09-03 [S] [expires: 2017-09-03]
      Keygrip = 5EB8133F4DE7DC128A98F368E053BBB605EAC82C

We then securely destroy the file containing the master key:

shred $HOME/.gnupg/private-keys-v1.d/4CE46814D2CD6D5D56D6E38B39FE725630FC4276.key

If we now list our keys again, we note that the master key is no longer available, as indicated by the hash.

$ gpg2 --list-secret-keys
sec#  rsa4096/0xC5D5DB322D019E3E 2016-09-03 [SC]
uid                   [ultimate] Your Name <user@domain>
ssb   rsa4096/0x3569358E7B3F5D41 2016-09-03 [E]
ssb   rsa4096/0x471A909DF2DE8245 2016-09-03 [S] [expires: 2017-09-03]

Sharing your public key

While the particularly paranoid would only share their public keys with people in their so-called Web-of-Trust, most of us wish to use the convenience of keyservers to distribute our public key. A good place to put your key is http://pool.sks-keyservers.net.

You can send your key using gpg with:

$ gpg2 --keyserver hkp://pool.sks-keyservers.net --send-keys 0xC5D5DB322D019E3E

After a little while, your key will be available for others to download.

Helpful references

I found the following sources of information were helpful in writing this article:

Article last modified on September 7, 2016 at 9:08 pm.

Leave a Reply

Your email address will not be published. Required fields are marked *