OpenPGP Introduction, Tutorial, and Howto
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.
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.
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.
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 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
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.
GnuPG Handbook - The official GnuPG handbook is very informative, but some of the
examples are slightly dated. E.g. the output listings from
- 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.cis 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.
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
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
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
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
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.
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: email@example.com Comment: You selected this USER-ID: "Matthew Lawrence Monaco <firstname.lastname@example.org>" 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 <email@example.com>
From here on out, all manipulation of your keypair is done interactively using
$ 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 <firstname.lastname@example.org> 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
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.
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
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 '*',
primary operate on the selected uid(s).
$ gpg --edit-key Matt ...snip keys... [ultimate] (1). Matthew Lawrence Monaco <email@example.com> [ultimate] (2) Matthew Lawrence Monaco (born 1985-09-27, Livingston, NJ, USA) [ultimate] (3)* Matthew Monaco <firstname.lastname@example.org> [ultimate] (4)* Matthew Monaco <email@example.com> 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.
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
key- Analogous to
uid, for selecting subkeys to use with other commands
addkey- Create a new subkey. Be sure to start with
--expertfor 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)
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>
As said above, key and subkey expiration is managed by the
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.
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,
just refuse to use it for new operations.
In many cases, you can revoke a (sub)key using thing
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 <firstname.lastname@example.org> 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
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
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-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
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
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)
We've already seen that your keys can be listed while in the GPG shell using the
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
subcommand. It is meant to be human-readable. If you want to parse the output,
--with-colons option prints in a parsable format.
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
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
Keyservers are public servers that host the information that is found in your
pubring.gpg file. When running
--keyserver option selects which
keyserver to use. I recommend choosing a keyserver and setting it in
Some popular keyservers include
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
Note that to e.g. encrypt a message to someone using their public key, you must
import it into your
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>
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
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.
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
--armor) option is used. To
later decrypt a document:
$ gpg --output unecrypted.doc --decrypt encrypted.doc.gpg
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
--symmetric to produce
documents which are signed and encrypted, both symmetrically and asymmetrically
encrypted, and all three.
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
--output option, the above commands either print to stdout or will
create a file with the same name as the input but with a
To verify signatures, use the
$ gpg --verify doc.sig
Or for detached signatures:
$ gpg --verify doc.sig doc
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
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.
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
@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
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.
delsig- delete signatures from your
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
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
--send-keys. If the key isn't actually on a keyserver,
probably the way to go.
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
ultimate are easy to
explain, you simply never trust or always trust signatures made by people with
these trust levels, respectively.
The other levels,
full, can be tweaked with the
--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.
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
--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
--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
--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.
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).
|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:
- Everyone sends their key information to a key master. This could simply be a key ID to be retrieved from a public key server
- The key master compiles a list of everyone's keys
- The list of keys is distributed to everyone in attendance
- Each person reads out their key information to verify that the list is correct
- Everyone else marks that the keys are valid on their own list
- In turn each person walks around and shows everyone their photo ID
- 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.
It is worth mentioning the command
$ gpg --list-packets <file>
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.
To be especially secure with your OpenPGP key, it is possible to keep a version
.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.
--homedir option is useful for setting a directory other than
when working with your offline master. To export you will want to do something
$ 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
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
$ 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 <email@example.com> uid Matthew Monaco <firstname.lastname@example.org> uid Matthew Monaco <email@example.com> 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
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.
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 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
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:
- Download the Arch Linux install ISO
- Verify the signature of the ISO
- Boot a computer to the installer
gnupgand the other packages while connected to the Internet
- Disconnect from the Internet
- Generate a master key and load it onto the smartcard
- 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!
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.
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
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
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.
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.
- Move to public github repo
- Discuss the cryptographic vs trust validy of sigs