Name Last Update
.gitignore Loading commit data...
LICENSE Loading commit data...
Makefile Loading commit data...
README.md Loading commit data...
github.css Loading commit data...
web-of-trust.svg Loading commit data...

OpenPGP Introduction, Tutorial, and Howto

Background

OpenPGP is a standard specified by RFC4880. There are numerous implementations but you only need to concern yourself with GnuPG. Werner Koch is the primary GnuPG developer and copyright holder and deserves to be mentioned by name; he is incredibly accessible and always helpful on the GnuPG mailing list. The importance of a full-featured, open source, OpenPGP implementation cannot be understated.

OpenPGP's purpose is to specify the practical use of public key cryptography. However symmetric cryptography and cryptographic hash functions play an important role as well.

Symmetric Encryption

A symmetric encryption algorithm (or cipher) uses the same key for encryption and decryption. It can be used by a single user, or by multiple parties. With multiple parties, exchanging the key must be done securely.

The strength of a symmetric algorithm rests with the quality of the key. The key should be hard to guess and sufficiently long. Symmetric algorithms generally use keys which are 128 to 512 bits long. To put that in perspective, there is estimated to be over 2265 atoms in the universe; brute force attacks are simply not practical. (There are a number of very amusing discussions on the Internet which estimate that brute-forcing a 128 bit value would e.g. require more energy than the Sun gives out in its lifetime). Attacks on symmetric algorithms generally involve finding weaknesses in random number generators which generate keys and obtaining keys directly through snooping, coercion, etc.

Common symmetric algorithms include AES (Rijndael), IDEA, Twofish, Blowfish, and Camellia. Furthermore, some of these have variants for multiple key sizes e.g., AES128, AES256, etc.

Asymmetric (Public Key) Encryption

Asymmetric (or public key) encryption algorithms use a pair of keys for encrypting data. We refer to one key as public and one as private. If the public key encrypts data, only the private key can decrypt it. Conversely, if the private key encrypts data, only the public key can decrypt it. This type of cryptography removes the need to communicate secret keys. Additionally it opens the door for more than just encryption with operations such as signing, certification, and authorization.

As with symmetric algorithms, the strength of public key algorithms rests with key size. Asymmetric keys are generally 1024 to 4096 bits long for a comparable level of security. This is because brute force attacks involve factoring numbers rather than guessing all keys in the key space.

Common asymmetric algorithms are RSA, ElGamal, DSA, and ECDSA.

Hybrid Ciphers

Because symmetric algorithms are generally more secure and more efficient, the encryption of bulk data and data streams tends to employ both models. Public/private keys are used to communicate a one-time session key. The session key is then used to encrypt data with a symmetric algorithm. This is how technologies such as TLS/SSL, SSH, and OpenPGP work.

Cryptographic Hash Functions

Hash functions map data of arbitrary length to a fixed size value (or digest). A common use of such functions is to verify data integrity. A cryptographic hash function has the following properties:

  • Pre-image resistance: it is not practical to find the original message from its hash value.
  • Second pre-image resistance: it is not practical to find a second message with the same hash value as the original.
  • Collision resistance: It is difficult to find two messages with the same hash value.

Because of these properties, passwords are often stored as hashed values. Authentication is performed by hashing a supplied password and comparing it to the stored hash value. It is poor practice to store passwords in plain-text, or even some reversible encoding such as base64. To mitigate against precomputed lookup tables of hash values, hashed passwords are often salted. That is, some random value is concatenated with the password prior to hashing.

Common hashing algorithms are SHA-1, SHA-256, SHA-512, MD5, RIPEMD, and Whirlpool. All of these are perfectly adequate for data integrity checking, but certain weakness in e.g. MD5 make it less suitable for all applications.

Random Numbers

Random number generation is an important precursor to strong cryptographic systems. Weak RNGs appear at first to be truly random, but in practice only produce values in a small subset of the intended output space and are easy to guessed by third parties.

True random number generators (e.g. /dev/random on Unix systems) use random inputs from the real world such as inter-interrupt timings and specialized hardware . These inputs are added to an entropy pool. The amount of entropy your computer has is a measure of how much randomness it is able to generate. When generating long keys (4096 bits) with GnuPG, the process might block for a long time (minutes) while enough entropy is generated by your mouse and keyboard movements, etc.

Psuedo random number generators begin with a seed and generate random values from it. The same seed will always produce the same sequence of 'random' numbers. This type of generator is suitable for simulations which do not need cryptographically secure random numbers and would benefit from the ability to store the seed for future replay. A popular example is Mersenne twister. On Linux systems, /dev/urandom is partially a psuedorandom number generator; it derives randomness from /dev/random, but also generates output continuously (it does not block). To save state between reboots, Linux distributions often save the state of /dev/urandom at shutdown and load it back in at boot.

Resources

  • GnuPG Handbook - The official GnuPG handbook is very informative, but some of the examples are slightly dated. E.g. the output listings from gpg have evolved.
  • GnuPG-users mailing list - The GnuPG user's mailing list is an excellent resource for help as well as great general discussion of security.
  • random.c - The Linux kernel's documentation of random.c is excellent and is worth a read.
  • OpenPGP Spec - RFC4880 specifies the protocol. While asymmetric keys are a mathematical concept, certificates, signatures, subkeys, revocations, etc are simply a defined standard.
  • gnupg.git - The GnuPG git repository is great for tracking development, seeing how things work, and even contributing.
  • GnuPG FAQ - You know what a FAQ is.

GnuPG Basics

The current version of GnuPG is 2.0.22 (2.1 has been in beta for a number of years). GnuPG version 1.4.x is still used for legacy reasons, but 2.x should be used where possible. On most systems gpg and gpg2 are available and refer to version 2.x. However, on Ubuntu 12.04, gpg still refers to 1.x. Make sure you know what version you are using:

$ gpg --version

GnuPG options and commands are summarized with gpg --help and detailed in man gpg. Data is generally stored in ~/.gnupg/ with the following structure:

~/.gnupg
├── gpg-agent.conf
├── gpg.conf
├── pubring.gpg
├── random_seed
├── secring.gpg
└── trustdb.gpg

gpg.conf stores options for the gpg command so you don't have to write them on the command line. The format of the file is one option per line, where options are the long options for gpg without the leading --. (Ditto for gpg-agent.conf).

pubring.gpg contains your public key(s) and subkey(s) as well as the public keys and subkeys of others. Public key can refer strictly to the raw data of a keypair, but in OpenPGP it generally includes other data like uids, photo-ids, and signatures of said key.

secring.gpg contains your private key(s) and subkey(s). The keys in this file are each encrypted using a password and symmetric cipher. Private key typically only refers to the secret key material and not to any other metadata. Note that in the upcoming GnuPG 2.1 secring.gpg and pubring.gpg are combined into a single file to make key management easier.

trustdb.gpg contains information about your Web of Trust. More on this below.

The Keys!

Before we generate our own personal, amazingly useful and powerful, OpenPGP keys, let's go over some concepts and properties of keys.

Your master key is your primary keypair. It is very important that you keep this safe. Some people (myself included) even keep this offline; we'll go over how to do this later. Along with your master key, you can have any number of subkeys. Cryptographically there is no difference between master keys and subkeys. The latter is defined in RFC4880 and is tied to its master by a couple of signatures.

There are four key capabilities, sign, certify, encrypt, and authenticate. In general keys can be one or more of these types. The ability to limit their use is not mathematical and is outlined in the OpenPGP spec (nb this may not be true for all algorithms...). However, master keys must at least have the certify capability and subkeys can not have the certify capability. This is because certification is the act of signing another public key and doing things like revoking a certification subkey would undermind the Web of Trust.

Keys also have some metadata such as (multiple) user IDs or uids which are a name, optional email address, and optional comment. They also have expiration dates so that if you lose your master private key it will eventually become invalid, however keys can be set to never expire. Other people's signatures of your key are also considered part of your key.

Finally, keys have a fingerprint. This is an immutable value that is derived from the immutable properties of a master key. It never changes so it can always be used as a convenient way to verify a master key. You don't want to visually inspect 4096 bits, do you?

Generating Your Keypair

The options I use below are, of course, optional and subject to your own preference. They are what I have chosen personally because I believe them to be the most secure options currently available.

We'll create a 4096 bit RSA master key which is certify only and expires in 5 years. The choices of 4096, RSA, and certify only are permanent; these are the only things you can never change. The expiration date, your subkeys, and uids are all changeable. The idea is that if you trust someone's master key, you trust all of these other components.

Using expert mode gives us option 8:

$ gpg --gen-key --expert
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)
   (7) DSA (set your own capabilities)
   (8) RSA (set your own capabilities)
Your selection? 8

Make sure that your current allowed actions are only 'Certify':

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

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

Choose the maximum of 4096 bits:

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

Expiration is debatable. Some say your master key should never expire. I feel that you should periodically prove you have control over your master key by updating its expiration. In fact, I choose to have mine expire the day before my birthday each year. Set the key to expire in 5 years:

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) 5y
Key expires at Wed 10 Oct 2018 08:56:27 AM MDT
Is this correct? (y/N) y

Finally, your key must have at least one uid:

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

Real name: Matthew Lawrence Monaco
Email address: matthew.monaco@0x01b.net
Comment:
You selected this USER-ID:
        "Matthew Lawrence Monaco <matthew.monaco@0x01b.net>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.

That's it! As mentioned before gpg will take a while to generate enough randomness for that whopping 4096 bit key. Continuing to type, play music, games, etc will help this go faster. Do not browse Facebook while this is happening; do you really want to look back 50 years from now and remember that Facebook was intimately involved in the entropy generated for your master key?

When your key is finished the details will be displayed, most importantly the ID and fingerprint.

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: key 0A645DD3 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:   3  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 3u
gpg: next trustdb check due at 2014-09-26
pub   4096R/0A645DD3 2013-06-26 [expires: 2014-09-26]
          Key fingerprint = F021 9725 3F0C A8EA 9AAB  0A05 5D3C 4525 0A64 5DD3 
uid                  Matthew Lawrence Monaco <matthew.monaco@0x01b.net>

From here on out, all manipulation of your keypair is done interactively using the gpg shell

$ gpg --edit-key Matt
pub  4096R/0A645DD3  created: 2013-06-26  expires: 2014-09-26  usage: C   
                         trust: ultimate      validity: ultimate
[ultimate] (1). Matthew Lawrence Monaco <matthew.monaco@0x01b.net>
gpg> 

The ID given can be your master key ID, any of the subkey IDs, or a partial string from one of your uids. The information printed is what you see from the list subcommand. For a complete list of available subcommands, type help.

Your next steps in setting up your keypair are to add any remaining UIDs that you would like and to setup encryption and signature subkeys.

Managing UIDs

Each keypair has at least one uid but multiple are quite common. You want one at least for each email address you will be using with OpenPGP. Additionally, you can add other information. For example, I chose to create a uid with my full name, no email address, and the date and place of birth in the comment.

The subcommands relevant to uids are uid, adduid, deluid, revuid, and primary. Below we see that I have 4 uids. My primary uid (1) is indicated by a '.'. Uids which are currently selected are indicated by a '*', deluid, revuid, and primary operate on the selected uid(s).

$ gpg --edit-key Matt
...snip keys...
[ultimate] (1). Matthew Lawrence Monaco <matthew.monaco@0x01b.net>
[ultimate] (2)  Matthew Lawrence Monaco (born 1985-09-27, Livingston, NJ, USA)
[ultimate] (3)* Matthew Monaco <matt@0x01b.net>
[ultimate] (4)* Matthew Monaco <matthew.monaco@colorado.edu>
gpg>

Note that uids are tied to your master key. You do not have uids that are specific to subkeys. Also, deluid should only be used on uids that have never been published. Once a uid has been released (published to keyserver, website, or emailed to someone), revuid should be used instead.

Managing Subkeys

OpenPGP supports subkeys for a few reasons. You may want to have keys of different sizes for different purposes. For example you may want a more efficient 1024 bit signing key, an balanced 2048 bit encryption key, and a really secure 4096 bit signing key. You may also want to use GnuPG in an environment you don't fully trust and wouldn't dare actually placing your private master key in case it is compromised and you need to revoke it. Furthermore, you may want the keys you use for day-to-day operations to evolve with new encryption algorithms and standards.

As with uids, subkeys are managed with the gpg shell. Subcommands which affect subkeys are:

  • key - Analogous to uid, for selecting subkeys to use with other commands
  • addkey - Create a new subkey. Be sure to start with --expert for the full range of algorithms and capabilities
  • delkey - Delete selected subkey(s)
  • expire - Change the expiration date for the master key or subkeys
  • toggle - Toggle between secret and public key listings
  • revkey - Revoke key or selected subkey(s)
  • enable/disable - Temporarily enable/disable keys from being used

We see that I have a certify only master key, a sign only subkey, and an encryption only subkey. I could also have subkeys which are both sign and encrypt (and even authorize), but my personal preference was to keep them separate. The master key is noted by pub/sec in column 1, the subkeys are noted by sub/ssb in column 1. The information contained in column 2 is the key size, key algorithm, and key ID.

$ gpg --edit-key matt
Secret key is available.

pub  4096R/0A645DD3  created: 2013-06-26  expires: 2014-09-26  usage: C   
                         trust: ultimate      validity: ultimate
sub  1024R/6F2435EA  created: 2013-06-26  expires: 2014-09-26  usage: S   
sub  2048R/DDEC74FE  created: 2013-06-26  expires: 2014-09-26  usage: E   
...snip signatures...

gpg> toggle

sec  4096R/0A645DD3  created: 2013-06-26  expires: 2014-09-26
ssb  1024R/6F2435EA  created: 2013-06-26  expires: never     
ssb  2048R/DDEC74FE  created: 2013-06-26  expires: never     
...snip signatures...

gpg>

Expiration

As said above, key and subkey expiration is managed by the expire subcommand. I have not seen any definitive best practice for choosing expiration dates for keys. However, I personally feel that yearly expiration dates for master keys is a good way of demonstrating that you still actively use your keys and haven't 'lost' them without the ability to revoke. Note that this does not prove an adversary doesn't have control over the key.

In my opinion the expiration of subkeys is less important. Losing a subkey (losing access to the file or forgetting a password) while retaining control of the master is highly unlikely. That said, I tend to set subkey expiration to match the master. Note that if the master key expires then so do all of the subkeys, so setting a subkey to expire further into the future than its master is no different than not having an expiration for that subkey.

Revocation

Revoking a key is a permanent way to announce that a key is no longer valid. OpenPGP specifies four reasons that you can give when revoking a key: no reason given, key has been comprimised, key is superseded, or key is no longer used. You can revoke individual subkeys or your master key (which implies all subkeys).

Note that a revoked key can still be used to decrypt data and such, gpg will just refuse to use it for new operations.

In many cases, you can revoke a (sub)key using thing revkey subcommand. However, you can generate a revocation certificate and save it to a file as a failsafe against losing your master key. Doing this is highly recommended.

$ gpg --output 0A645DD3.revoke.asc --gen-revoke matt

sec  4096R/0A645DD3 2013-06-26 Matthew Lawrence Monaco <matthew.monaco@0x01b.net>

Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
  0 = No reason specified
  1 = Key has been compromised
  2 = Key is superseded
  3 = Key is no longer used
  Q = Cancel
(Probably you want to select 1 here)
Your decision? 0
Enter an optional description; end it with an empty line:
> This is a failsafe revocation certificate, likely used for a lost key.
> 
Reason for revocation: No reason specified
This is a failsafe revocation certificate, likely used for a lost key.
Is this okay? (y/N) y

Make sure you keep this file private, anyone can now use it to revoke your key. The certificate isn't that long, so you could even print it out as a backup.

In the event that you are revoking a key you still control, you will likely use one of the other reasons listed above. For a superseded key, you might want to include the fingerprint of your new key in the optional description. Also, when superseding a key you should sign the new key with the old one. This will help convince previous signers to resign your key and rebuild their Web of Trust.

Another thing you can do is designate a revoker for your key. This is done using the addrevoker subcommand. It creates a certificate which enables another person to revoke your key. The designated revoker can be published (default), or be secret, in which case only the two of you will know about it until the occasion that they revoke your key. Designating a revoker is similar to sending a revocation certificate to someone. It is no something that can be undone!

GPG Agent

Most OpenPGP operations require the private material of your master key or a subkey. Recall that this material is password protected (symmetrically encrypted) in secring.gpg. However, it can be really inconvenient to enter your password every time you do something with gpg.

The gpg-agent makes life easier. It prompts you for your password once, and then holds your private key material securely. It speaks a protocol to allow gpg operations such as signing and key maintenance without ever releasing your private data. Programs such as gpg find the agent through GPG_AGENT_INFO environmental variable, which gpg-agent prints when starting. Therefore, the agent is typically started in a session startup script:

$ eval $(gpg-agent --daemon)

Desktop environments such as GNOME provide the gnome-keyring-daemon which also speaks the gpg agent protocol, therefore you typically do not need to worry about starting it yourself.

By the way, this is very similar to how the more well-known ssh-agent works. In fact, gpg-agent speaks the SSH agent protocol so you don't need to run both programs! To do this, simply start the agent as such:

$ eval $(gpg-agent --daemon --enable-ssh-support)

Listing Keys

We've already seen that your keys can be listed while in the GPG shell using the list and toggle subcommands. There are also some options to print your and everyone else's keys from the command line.

To print public keys, any of the following work:

$ gpg -k
$ gpg --list-keys
$ gpg --list-public-keys

To print public keys, along with signatures:

$ gpg --list-sigs
$ gpg --k --with-sig-list

To print private keys:

$ gpg -K
$ gpg --list-secret-keys

The output from these commands is similar to what you see from the list subcommand. It is meant to be human-readable. If you want to parse the output, the --with-colons option prints in a parsable format.

Disseminating Keypairs

All of the commands we have seen such as creating your key, adding subkeys, adding uids, revoking keys, and revoking uids are local to your .gnupg directory. Anything you do still needs to be disseminated to the outside world. There are two ways to communicate the state of your keys: keyservers and manual import/export.

Keyservers

Keyservers are public servers that host the information that is found in your pubring.gpg file. When running gpg, the --keyserver option selects which keyserver to use. I recommend choosing a keyserver and setting it in gpg.conf. Some popular keyservers include pgp.mit.edu, keys.gnupg.net, and keyserver.ubuntu.com. All of the major keyserver speak a distributed protocol to relay information among one another, so you only need to pick one that works well for you. I've been happy with pgp.mit.edu. The data you send to a keyserver is cumulative. You can never remove things from a keyserver, only add revocations. This is why the del* subcommands aren't usually what you want to use.

Note that to e.g. encrypt a message to someone using their public key, you must import it into your pubring.gpg, gpg does not transparently use keyservers for any operations.

Many of these commands work with multiple keys, but typically are used with only one. They are used to send and receive new uids, revocations, subkeys, and signatures.

To send a key or update it on the keyserver:

$ gpg --send-keys matt

To retrieve a key:

$ gpg --recv-keys 0A645DD3

To update your local copy of the keys on your keyring:

$ gpg --refresh-keys

And, to search for a key on a keyserver:

$ gpg --search-keys <string>

Alternatively, most keyservers have a web interface. For example pgp.mit.edu, or this fairly slick one from [Fedora](https://keys.fedoraproject.org "keys.fedoraproject.org).

Local Import/Export

It is also sometimes useful to work with OpenPGP keys and metadata directly. These commands are fairly straightforward.

To import/merge public and/or private keys:

$ gpg --import <file>

The export command, by default, exports all public keys (yours and other's) in a binary format:

$ gpg --export [<ids>] > file.gpg

To export just one public key, in an ASCII armored format which is better suited for displaying on a web page or inline in an email:

$ gpg -a --export Matt > matts-public-key.asc

You can also export secret keys (including all subkeys) or all subkeys without the master:

$ gpg --export-secret-keys > secrets.gpg
$ gpg --export-secret-subkeys > secrets-sub.gpg

Unfortunately there isn't currently a straightforward way to export a single subkey, but IMO would be a useful feature.

You can also import keys over HTTP, FTP, LDAP, etc, although I haven't personally had occasion to use this:

$ gpg --fetch-keys <URIs>

Finally, you can import and export the data from trustdb.gpg, but we'll cover this more later in the Web of Trust section:

$ gpg --import-ownertrust < file.txt
$ gpg --export-ownertrust > file.txt

Basic Operations

Encryption, signing, and authentication are the whole point to OpenPGP. All of the other sections in this documents are simply about setting yourself up to effectively perform these actions. OpenPGP is most widely used with via email, so see the section below on the Enigmail Thunderbird extension for GnuPG.

Encryption

When you encrypt data with gpg, a random session key is used to symmetrically encrypt the data and the public key of each recipient is to asymmetrically encrypt the session key. If you want to be able to decrypt the data, be sure to add yourself to the recipient list!

$ gpg --output encrypted.doc.gpg --encrypt --recipient Alice --recipient Bob unencrypted.doc

This will produce a binary file unless the -a (--armor) option is used. To later decrypt a document:

$ gpg --output unecrypted.doc --decrypt encrypted.doc.gpg

Also, because gpg requires support for symmetric encryption, it might as well expose it as a feature to the user:

$ gpg --output encrypted.doc.gpg --symmetric unencrypted.doc

You can mix and match --encrypt with --sign and --symmetric to produce documents which are signed and encrypted, both symmetrically and asymmetrically encrypted, and all three.

Signing

Signing with public key cryptography is taking a hash, or checksum, of a document and then encrypting it with a private key. Others can then decrypt the checksum with your public key and recalculate the checksum to compare and prove the original document is exactly what you said it was. GnuPG supports a few different formats for signatures.

The basic form creates a binary file which includes the original document as well as the signature. This form isn't actually too widely used on the Internet for distributing software/documents.

$ gpg --output doc-and-sig.sig --sign doc

You can also create just the signature, so to verify later, the you or your recipient must also have the original document. Software is generally distributed on the Internet as .tar.xz and .tar.xz.sig so as not to inconvenience those who don't care about the signature.

$ gpg --output doc.sig --detach-sign doc

Finally, you can make a clear signed signature which includes the original document and the signature. This is the format most often used for email signatures.

$ gpg --output doc.sig -a --clearsign doc

Without the --output option, the above commands either print to stdout or will create a file with the same name as the input but with a .sig extension.

To verify signatures, use the --verify option:

$ gpg --verify doc.sig

Or for detached signatures:

$ gpg --verify doc.sig doc

Authentication

OpenPGP keys can also be used for authentication. However, there aren't any manual commands that use this capability. SSH, for example, uses its own public/private keypair implementation for authentication. GnuPG is distributed with a small utility to convert OpenPGP keys to SSH keys; it is aptly named gpgkey2ssh.

Other People's Keys

OpenPGP doesn't have much purpose without other people! To be a good citizen of the OpenPGP community, you will need to sign other people's keys from time to time and publish the signatures to help further legitimize others' keys. Additionally, for you own self-serving purpose, gpg will bark at you when doing operations using other people's keys which you haven't signed.

Signing

To be specific, you do not actually sign someone's key, you actually sign uid(s) associated with the key. For example you may be willing to sign the key for my @colorado.edu email address, but not an email address for a former school that you haven't verified I am associated with. I also have a uid with some of my birth information; you may want to view my birth certificate before you sign it.

The subcommands associated with uids are:

  • uid - select one or more uids to sign
  • sign - sign the selected uids
  • lsign - locally sign the selected uids. These will not be exported with --export or --send-keys
  • tsign - sign the selected uids with trust (not generally used)
  • nrsign - sign the selected uids with non-revocable signature
  • *sign - combinations of the above, e.g. nrlsign
  • delsig - delete signatures from your pubring.gpg
  • revsig - revoke signatures

As with managing your own uids, delsig is not recommended for signatures that have already been published, use revsig instead. The tsign subcommand is a way to publish your trust in a key (see Web of Trust below), but is typically used among specific groups; unless you are sure about what you are doing, tsign is not for you. I'm not positive about real use-cases for nrsign, but it's there and you probably don't want to use it.

Once you have signed a uid(s) on someone's key, you'll want to publish them using --send-keys. If the key isn't actually on a keyserver, lsign is probably the way to go.

Revoking

Revoking a signature (like revoking a your own key) is permanent. You'll generally want to do this if you believe someone's key has been compromised, you know they no longer are in control of a specific email address (left a company), etc. If someone revokes their own key, you do not have to bother revoking the uids.

Web of Trust

When you sign a uid, you are telling gpg and the rest of the world (if the signature is published) that you trust that the key belongs to the owner. Some people even only sign uids for people that have demonstrated a certain level of competence with OpenPGP. However, it is not practical for you to verify the keys of everyone you might interact with. This is where the Web of Trust comes in.

The Web of Trust is a way for gpg and yourself to trust the validity of keys indirectly by e.g. trusting the signatures made by someone who you yourself trust. There are a few levels of trust: unkown, none, marginal, full, and ultimate. The levels none and ultimate are easy to explain, you simply never trust or always trust signatures made by people with these trust levels, respectively.

The other levels, marginal and full, can be tweaked with the gpg settings --marginals-needed and --completes-needed. The defaults are 3 and 1, respectively. This means that a key which you have not signed needs at least 3 signatures from people you marginally trust or 1 from a person you fully trust. One more option --max-cert-depth, which defaults to 5, says that at most follow the Web of Trust 5 hops from a key which you have actually signed.

The subcommand trust is used to change your trust level of a key. Your trust data is stored in trustdb.gpg. Trust values are entirely local to you, everyone has their own view of the Web of Trust. (Yes there is tsign but you likely won't be using this). The commands --export-ownertrust and --import-ownertrust can be used to export/import data from your trustdb for backups, or if you feel the need to share your trust information. For completeness, --update-trustdb and --check-trustdb can be used to force some trustdb maintenance that gpg normally does on-demand.

Below is Web of Trust example which I have recreated exactly from the GnuPG Handbook. It uses --marginals-needed=2, --completes-needed=1, and --max-cert-depth=3. (These are not the defaults, but simplify the example). If it's not obvious, the arrows indicate that e.g. Alice has (verified and) signed (a uid on) Blake's key.

Web of Trust

The table below represents the Web of Trust form Alice's perspective. Each row is a different example. With the given trust levels for each key (on the left), Alice sees the given validities (on the right).

trust validity
marginal full marginal full
Dharma Blake, Chloe, Dharma, Francis
Blake, Dharma Francis Blake, Chloe, Dharma
Chloe, Dharma Chloe, Francis Blake, Dharma
Blake, Chloe, Dharma Elena Blake, Chloe, Dharma, Francis
Blake, Chloe, Elena Blake, Chloe, Elena, Francis

Key Signing Parties

Key signing parties are a convenient way to have your key verified and to verify the key of others. At a key signing party, no actual signing takes place. This would open everyone up to some attacks (such as someone seeing you type your passphrase). It also isn't practical for people who keep offline master keys on a computer which isn't connected to the Internet. Instead a list of public keys is accumulated and each person verifies his or her key size, key fingerprint, and identity with a photo ID. (The key size is important because two keys with different sizes could in fact share a fingerprint).

Each person should bring:

  • A photo ID
  • Their own copy (a printout perhaps) of their key size and fingerprint

Then, one possible procedure would be:

  1. Everyone sends their key information to a key master. This could simply be a key ID to be retrieved from a public key server
  2. The key master compiles a list of everyone's keys
  3. The list of keys is distributed to everyone in attendance
  4. Each person reads out their key information to verify that the list is correct
  5. Everyone else marks that the keys are valid on their own list
  6. In turn each person walks around and shows everyone their photo ID
  7. Everyone else marks that the identification is valid on their own list

Now everyone has a list of keys which are valid and belong to the person listed. If the keys aren't already on a keyserver, the key master can distribute a digital copy which can be verified against the printed list.

At this point signing can take place. Each person should sign the keys which they want, and then use the --send-keys command to upload the signatures to a keyserver. He or she should also periodically do a --refresh-keys to pull down the signatures of others, especially those of his or own own key.

Misc

OpenPGP Files

It is worth mentioning the command

$ gpg --list-packets <file>

where file is anything gpg-ish such as pubring.gpg an encrypted document, a detached signatures, a clearsigned signature, an exported public or private key, etc. This command will list all of the information in file and is usefully for debugging, sanity checks, and learning.

Offline Master

To be especially secure with your OpenPGP key, it is possible to keep a version of your .gnupg directory handy without the master key. That way, if your computer is compromised, or you want to use your keys on a less trusted computer, you can simply revoke the subkeys without worrying about rebuilding the signatures which you have worked hard to accumulated.

You can sign, encrypt, verify, and decrypt without your master key. Your master key is required to certify (sign another key), add uids, revoke uids, add subkeys, revoke (sub)keys (if you do not have a pre-generated revocation certificate available), and change expiration dates.

You can convert an existing setup to offline master, or you can start fresh by generating your master key on an offline computer and extract the public keys and private subkeys to e.g. a thumb drive and transfer them to your primary operating system. Your offline master doesn't necessarily need to be offline, it can also be in a directory other than ~./gnupg and be protected by a much longer, less convenient to type password. It can also just be stored on a thumb drive which you occasionally plug in to your main machine. See the smartcard section below for a possible 'recipe' for generating an offline master; but replace smartcard in step 6 with thumb drive.

The --homedir option is useful for setting a directory other than .gnupg when working with your offline master. To export you will want to do something like:

$ gpg --homedir /mnt/offline.gnupg --export <id> > public.gpg
$ gpg --homedir /mnt/offline.gnupg --export-secret-subkeys <id> > private.gpg
$ gpg --delete-secret-keys <ID>
$ gpg --import public.gpg
$ gpg --import private.gpg

Unfortunately, gpg does not properly merge the secret portion of your keys when importing updated data (the public portion works find). I believe this to be a bug, but it is why you must do --delete-secret-keys before re-importing.

When your private master key is unavailable, it will be indicated by sec#:

$ gpg -K
/home/matt/.gnupg/secring.gpg
-----------------------------
sec#  4096R/0A645DD3 2013-06-26 [expires: 2014-09-26]
uid                  Matthew Lawrence Monaco (born 1985-09-27, Livingston, NJ, USA)
uid                  Matthew Lawrence Monaco <matthew.monaco@0x01b.net>
uid                  Matthew Monaco <matt@0x01b.net>
uid                  Matthew Monaco <matthew.monaco@colorado.edu>
ssb   1024R/6F2435EA 2013-06-26
ssb   2048R/DDEC74FE 2013-06-26
ssb   1024R/13B1A76A 2013-08-29

Note that GnuPG version 2.1 (currently in beta) will be combining secring.gpg and pubring.gpg so it should hopefully make the process smoother. Currently, uids are duplicated in each file and can get out of sync with one another; this isn't a big deal but is annoying in my opinion.

Enigmail

Most day-to-day use of OpenPGP is typically done over email. You can sign every message you send, regardless of the recipients' use of OpenPGP, or you can sign messages that contain public but important information such as official announcements. Also, email makes it really easy to distributed encrypted data to recipients which are also using OpenPGP.

Unfortunately the big webmail providers like Gmail, and uh..., Gmail, do not support OpenPGP. However, there is an extension for Thunderbird called Enigmail which is a nice and fully functional wrapper around GnuPG (you must have GnuPG installed).

Smartcards

Smartcards are the most secure way to use OpenPGP. Smartcards hold at the least the private portions of your master key, subkeys, or both and never reveal them to the outside world. They are sort of like a hardware gpg-agent. High quality smartcards will even self destruct if someone attempts to tamper with them to physically extract the key material.

Furthermore some smartcards can generate keypairs so they are absolutely never exposed to the outside world. Personally, I trust GnuPG more than anything so if I had a smartcard (which I don't) I would generate a master key by:

  1. Download the Arch Linux install ISO
  2. Verify the signature of the ISO
  3. Boot a computer to the installer
  4. Update gnupg and the other packages while connected to the Internet
  5. Disconnect from the Internet
  6. Generate a master key and load it onto the smartcard
  7. Power off the computer, leaving no trace (even if there was e.g. a keylogger which somehow made its way onto the installer.

The biggest drawback to smartcards is that current offerings all seem to have one limitation or another. In my opinion, an ideal smartcard would be a small USB device (to avoid requiring an actual smartcard reader) which could hold a 4096 bit master key and 2 or 3 4096 bit subkeys. Please let me know if you know of such a device!

TLS/SSL

People often are confused about the difference between OpenPGP and TLS/SSL, so it's worth covering here.

  • OpenPGP and TLS/SSL are both standards.
  • Both use the same sets of symmetric, asymmetric, and hash algorithms.
  • GnuPGP, PGP, and others are implementations of OpenPGP. OpenSSL, GnuTLS, and others are implementations of of TLS/SSL.
  • OpenPGP is geared towards files and blocks of data. TLS/SSL is geared towards streams of data.
  • OpenPGP's trust model is generally referred to as Web of Trust. The TLS/SSL trust model is generally referred to as Public Key Infrastructure (PKI).

In my opinion, GnuPGP is the preferred OpenPGP implementation. Unless you are being pedantic about licensing, OpenSSL is the preferred TLS/SSL implementation.

The Web of Trust model, described above, is a decentralized system. The PKI system relies on centralized certificate authorities. Your operating system or web browser typically comes with the public keys of the well-known, trusted, certificate authorities. You can also install them manually. Your browser, for example, will then complain if you visit a website with a key not signed by a certificate authority; in such a case your communication is still secure with the endpoint, but the endpoint itself hasn't been verified to be what it says it is. If you get a certificate error when visiting a major website, such as a bank, you are likely the victim of a man-in-the-middle attack. Certificate authorities are paid to sign keys along with other fields such as verified URLs, company names, addresses, etc.

SSH

OpenSSH as an awesome utility that also makes use of public/private keys so I want to mention it here. Like OpenPGP and TLS/SSL, SSH is a protocol and OpenSSH is one such implementation. The OpenSSH key system is used for authentication and is implemented directly in SSH. However, the keys are compatible and using gpgkey2ssh you can convert your OpenPGP key to the SSH format. Once authentication has been established, SSH uses OpenSSL for a secure channel.

In my opinion it would be wonderful if OpenSSH simply had direct GnuPG integration and spoke directly to the gpg-agent to look for keys with the authorization capability. As mentioned above, gpg-agent can actually replace the ssh-agent, but the integration still isn't as seamless as it could be. For example, OpenSSH has agent forwarding so that you only need to store your private key on your local computer; you can ssh from machine A to machine B, and then from machine B to machine C without having to store your private key on machine B. There is no such support for gpg, so it is a pain to use on remote computers.

Conclusion

I hope this document has proved useful to beginners as wells as more experienced users that need an occasional reference. Each section is meant to be somewhat self contained, providing all of the information generally needed for a particular topic. If you find anything vague, think something is missing, or most importantly see errors, please contact me!

Public key cryptography and OpenPGP are awesome. I wish they were ubiquitous. They are both more secure and more convenient than typical passwords or ID numbers. Imagine a world where you started your car or entered your home using your private key; or temporarily gave access to a friend by signing his or her key. Your birth certificate could be a document that's actually signed by your hospital, your address in a certificate signed by an official of your current locality, and your official identification derived from your key rather than some mixture of the horribly overused social security number or other-wise public information such as birth date. Marriage and driver's licenses, deeds, credit cards, etc could all be based on public key cryptography with signatures from the appropriate authorities.

Sure, the technology is not perfect and there are weakness, but they are less compelling, in my opinion, than weaknesses with current systems. For example, someone could take a photo of your house key with a telescopic lens and reproduce it. Or, accumulate bits of legitimate information about yourself and put them together to take your identity. Public key cryptography is amazing because there are physical ways to have secure communication and identity management without ever actually exposing your private data.

The only barrier preventing ubiquitous use of this technology is education. So get out there, use OpenPGP, explain it to people who are not yet informed, and exercise your right to privacy and security.

Credits

This document was assembled by Matt Monaco with help from Andy Salyer. It is based off of some information and structure from the official GnuPG Manual as well as Wikipedia.

This document is licensed under the Creative Commons BY-NC-SA License. In short, you are free to share and adapt it provided that you attribute the work to its original authors (including the GnuPG Handbook and Wikipedia), are not doing so for commercial purposes, and relicense under a compatible license to this one.

TODO

  • Proofread
  • Move to public github repo
  • Discuss the cryptographic vs trust validy of sigs