#g33kr_

[EAtT] Getting started with GPG

About GPG

GNU Privacy Guard (GPG) is a powerful security tool for encrypting your stored data and communications. It is a Free Software implementation of Pretty Good Privacy (PGP) and is compliant with the OpenPGP standard. GPG can be used to secure files and other forms of digital communications such as emails and chats, using strong cryptography.

Creating your keys

In order to send and receive signed or encrypted messages or files, you must first install GPG and generate a GPG key pair. For a step-by-step guide to creating a strong GPG key pair, see One GPG key pair (to rule them all). However, before you create your keys and start using GPG, I recommend familiarizing yourself with some of the core concepts of GPG and public key encryption.

Common terms

Here are some commonly used terms in cryptography that you'll want to be familiar with:

  • Encryption: the obfuscation of data into a form that is only readable by someone with the knowledge of a secret.

  • Key: A key is a unique cryptographic certificate used to encrypt or decrypt data. GPG typically uses two keys, a public key and a private key (more on those below).

  • Keyring: A collection of encryption keys. With GPG, you will typically have two keyrings - a public keyring and a private keyring.

  • Signature/signing: a digital mark on a piece of data that is verifiable by the reader, and which proves the data was written by the person who signed it and has not been altered in transit.

  • Algorithm: A mathematical methodology for solving a problem. In the case of cryptology, the problem is the generation of difficult-to-guess random numbers, typically through the factoring of large primes.

  • Cipher: A specialized algorithm used for encryption and decryption of data. AES is a commonly-used symmetric key cipher. RSA and DSA are asymmetric ciphers typically used to generate GPG/PGP key pairs.

  • Message digest (or "hash"): A calculation ("hash function") performed on data of arbitrary length that produces a fixed-length bit string. Also called a "one-way transform," because a hash cannot be decrypted. A hash can only be compared to another hash to determine if the same data was entered (since hashing is deterministic, the same data input will always produce the same cryptographic checksum). Message digests are commonly used for the secure storage of passwords (without knowledge of the password itself) and to ensure the integrity of a unit of data (e.g., if a file or message is complete and unaltered). The SHA-2 family of hash functions (including SHA-256 and SHA-512) are most commonly used with GPG.

  • Fingerprint: A commonly used name for the hash of a cryptographic key. Every GPG key has a unique fingerprint that identifies it, and no two keys of the same type and length should ever have the same fingerprint.

  • Key length: The general measure of the strength of an encryption key, with larger crypto keys being harder to break. With RSA keys, 2048 bits is considered the minimum secure key length (3072- and 4096-bit keys are also possible).

  • Web of trust: A construct of transitive trust between individuals, relying on the trust of a known entity to validate the identity of an unknown entity. This can be best illustrated by the simple example "A trusts B. B trusts C. Therefore, A trusts C." With GPG, trust relationships are established through the signing of public keys by other parties, and an assignment of trust in the keys that were used to sign. When you view someone else's public key you may place some level of trust in the identity of the key's owner if you trust that one or more of the individuals who have signed that public key have taken steps to properly validate the identity of the key's owner. Usually, the person signing a public key knows the owner personally, or the key owner has produced some form of ID in person for the signer to validate.

Symmetric vs. asymmetric encryption

GPG can be used to perform both symmetric and asymmetric encryption of data. Both methods secure the data cryptographically, but they vary in how encryption secrets are managed.

Symmetric encryption

Symmetric encryption (also called "private key" encryption) is essentially the encryption of data with a shared secret. The secret key (password/passphrase) is chosen by the user and employed by GPG to perform the encryption and the decryption of a piece of data using a symmetric cipher (typically, AES-256). No public keys are involved, and the secret key is shared between the sender and recipient through some out-of-band method, so that the recipient may decrypt the data.

For example, if you had a file that you wanted to send securely to a friend you could encrypt it with a simple passphrase using GPG. Here's our file:

$ cat secretfile.txt
Mary had a little lamb. Don't tell anyone.

You obviously want to protect this sensitive information, so you encrypt the file with a passphrase.

$ gpg -ac -o secretfile.asc secretfile.txt
[prompt for passphrase]

GPG will read the secretfile.txt input, prompt you for a password or passphrase, perform symmetric encryption (-c) using that passphrase as a secret, and then store the ASCII armored (-a) data in an output (-o) file called secretfile.asc. If we look at the contents of that file, we'll see it's now encrypted:

$ cat secretfile.asc
-----BEGIN PGP MESSAGE-----

jA0ECQMK1Mh74tOXDiH/0mwBHKVEKkBbOrRqXDrI1IQzJE+ccxSTZQsKKO9pD+nf
r4XIJzVUhpLqwM/h67XEfr5+gODzILyGfvw+IHRgxZSA0u5nJDQkj6RxqK2ZXkdZ
ahb5Yn1sC1BODC5PoGSqYZJj/adGUrO/ppLSbCw=
=9zIh
-----END PGP MESSAGE-----

You can now safely send this encrypted file over public channels (email, web forum, etc.) and then communicate the password to your friend privately (e.g., by phone or in person). When he receives the file, your friend can decrypt (-d) the file using the password:

$ gpg -d -o secretfile.txt secretfile.asc
[prompt for passphrase]
$ cat secretfile.txt
Mary had a little lamb. Don't tell anyone.

Symmetric encryption is appropriate for some use cases, but due to its nature it presents three major problems:

  1. You have to somehow communicate the password securely to the intended parties in order for them to decrypt the data.
  2. Anyone (intended or otherwise) who learns the password can decrypt the data.
  3. Passwords and passphrases that are easily communicated may also be easier to guess.

Asymmetric encryption

To eliminate those issues we can use asymmetric encryption (also known as "public key" encryption). Asymmetric encryption breaks the security process into two distinct phases - encryption and decryption - and uses different keys for each step, with the respective keys held by different parties. The two keys involved are called the public key and the private key.

Public key

The public key (as its name implies) is public information. It is not secret, and you do not need to secure it. To the contrary, your public key is distributed openly, often published on a webpage or uploaded to public keyservers for distribution. Through the process of exchanging encrypted messages you will collect other people's public keys and add them to your own keyring. Others will add your public key to their keyring, and will use your public key to:

  • encrypt data sent to you.
  • verify data signed by you.

Private key

The private key is your secret key and it must be closely guarded. You will use your private key to:

  • sign data to be verified by others
  • decrypt data sent to you

If your private key is ever compromised, it can be used to fraudulently sign messages or files as yourself, or decrypt files or messages sent to you. Further, if you were ever to lose your private key, you would no longer be able to sign new files with that key, or decrypt files or messages that were previously encrypted with that key. For these reasons, you must take great care to ensure the integrity of your private key from compromise or loss.

In reality, even when using asymmetric encryption to send a message, the encryption of the message body itself is still done with a symmetric key. RSA is actually a slow algorithm, so using it to encrypt a large message or file would take prohibitively long. Instead, GPG generates a complex, random secret (called a "session key") and performs encryption of the message body using that secret and a fast symmetric cipher such as AES-256. The session key itself (which is small compared to the message body) is then encrypted with the recipient's RSA public key, and included along with the message. When the recipient receives the encrypted message and session key, they first decrypt the session key with their RSA private key, then use the decrypted secret to decrypt the message body with the symmetric cipher. GPG handles all of this behind the scenes.

Using GPG

Public key encryption in practice is actually quite simple, but initiates often find themselves confused or overwhelmed by the terminology involved and the somewhat counter-intuitive nature of the thing. Once you grasp some core concepts however, you will likely find using GPG to be very straightforward and easy.

The basics in a nutshell

  • You sign your own messages with your private key.
  • You verify the signatures of others with their public key.
  • You decrypt encrypted messages sent to you with your private key.
  • You encrypt messages to others with their public key.

One important thing to remember from the above is that once you encrypt a message to someone else, you cannot read the encrypted message - even though you're the one who encrypted it! The only way to decrypt the message is with the private key of the recipient, which you don't have. Because of this, when sending encrypted emails to others many email clients also provide the option to encrypt a copy to yourself. By doing so, the contents of the original message will remain securely encrypted in your sent items but you will be able to go back later and decrypt the message yourself, if necessary. If you don't keep an encrypt-to-self copy, you'll have to rely on memory to determine what was said (or keep an unencrypted copy somewhere, which may defeat the point of encrypting it in the first place).

Viewing your keyrings

As said before, you will typically have two GPG keyrings - a public keyring and a private keyring. Your private keys are stored in the private keyring. Your public key (and the public keys of others) are stored in the public keyring.

The public keyring does not contain any secret information. However, viewing the contents of your public keyring may give someone an idea of the people with whom you communicate (which may or may not be sensitive information). If lost or destroyed, the public keyring can be recreated simply by downloading and importing the public keys again.

The private keyring contains your GPG private key(s) and must be secured carefully against theft or loss.

To view the contents of your public keyring, use the command:

$ gpg -k

/home/rdemo/.gnupg/pubring.kbx
------------------------------
pub   rsa4096/0xEC837AE765CD8817 2011-09-11 [SC] [expires: 2018-01-01]
      Key fingerprint = 53C1 D387 1842 2B2C 6F28  F9AF EC83 7AE7 65CD 8817
uid                    [unknown] Tony Example <tony@example.com>
sub   rsa4096/0xD152C259D0EFB4D5 2011-09-11 [E] [expires: 2018-01-01]

pub   rsa4096/0xE4211AD362149FC8 2016-12-31 [SC] [expires: 2018-12-31]
      Key fingerprint = 86DF 43C5 7A27 9918 E392  CD43 E421 1AD3 6214 9FC8
uid                   [ultimate] Rick Demo <rick@demo.com>
sub   rsa4096/0xC733B294EEE2AC54 2016-12-31 [E] [expires: 2018-12-31]

This is Rick Demo's public keyring. We see his own public key as well as the public key of Tony Example, with whom Rick exchanges encrypted messages. The public signing keys are denoted by 'pub' and the encryption subkeys are identified by 'sub'. A GPG key consists of multiple parts: the main (or "primary") key and one or more subkeys. It is typical for encryption [E] to be performed using a subkey, while the primary key is used for signing and certification [SC]. In fact, different subkeys can (and should) be used for each of the signing, encryption, and authentication capabilities (more on capabilities below). The creation of subkeys is covered in more detail in One GPG key pair (to rule them all).

To view the contents of your private keyring, use the following command (note, this time with an uppercase 'K'):

$ gpg -K

/home/rdemo/.gnupg/pubring.kbx
------------------------------
sec   rsa4096/0xE4211AD362149FC8 2016-12-31 [SC] [expires: 2018-12-31]
      Key fingerprint = 86DF 43C5 7A27 9918 E392  CD43 E421 1AD3 6214 9FC8
uid                   [ultimate] Rick Demo <rick@demo.com>
ssb   rsa4096/0xC733B294EEE2AC54 2016-12-31 [E] [expires: 2018-12-31]

The output looks very similar to the first command, but this time we only see Rick's private key (denoted by 'sec') and the private encryption subkey (denoted by 'ssb').

The anatomy of a GPG key

The output from gpg -k might look kind of confusing at first with its strings of numbers and letters. But once you learn to read the structure of it, it's really quite simple.

This first line shows the primary key. In this case, that's a public key (denoted by 'pub'):

pub   rsa4096/0xE4211AD362149FC8 2016-12-31 [SC] [expires: 2018-12-31]

The type of key is RSA and the length of the key is 4096 bits. After the '/' character is the key's ID (0xE4211AD362149FC8). This is a unique identifier for the key, and this ID is shared by both the public and the private key (since they are a pair). The date that follows is the date the key was created.

The code that follows shows the key's capabilities, which can be one or more of:

[C] certification
[S] signing
[E] encryption
[A] authentication

Certification is the capability of a key to sign other keys. The primary key will always have the certification capability. In this case, we can see it also has the signing capability, meaning it can be used to cryptographically sign messages or files. The last part of the first line shows the expiration date of the key (more on that later).

This next line shows the key's fingerprint, the hash that uniquely identifies this key.

Key fingerprint = 86DF 43C5 7A27 9918 E392  CD43 E421 1AD3 6214 9FC8

The next line shows the user ID (uid), or owner of the key. A key can have multiple UIDs assigned. For instance, if the same person had multiple email addresses with which they used the key. The box that says 'ultimate' is the calculated validity level that has been assigned to the UID by GPG. In this case, we're viewing Rick Demo's public key in Rick's own keyring and so GPG regards the UID with ultimate validity automatically. For foreign keys (public keys of other people) the validity of a given UID will be calculated based on the signatures that are applied to the UID, and the trust assigned to those signing keys (more on that later).

uid                   [ultimate] Rick Demo <rick@demo.com>

Lastly we have a line for the subkey, in this case an encryption [E] subkey. Note the information is similar to the primary key, except that the key is denoted with 'sub' to show that it is a subkey of the primary key.

sub   rsa4096/0xC733B294EEE2AC54 2016-12-31 [E] [expires: 2018-12-31]

If we look at the output of gpg -K we see similar lines for the private key.

sec   rsa4096/0xE4211AD362149FC8 2016-12-31 [SC] [expires: 2018-12-31]
      Key fingerprint = 86DF 43C5 7A27 9918 E392  CD43 E421 1AD3 6214 9FC8
uid                   [ultimate] Rick Demo <rick@demo.com>
ssb   rsa4096/0xC733B294EEE2AC54 2016-12-31 [E] [expires: 2018-12-31]

Notice the respective key IDs for the primary and subkey are the same as those on the public key, because they are the private half of those same keys. Every key has two parts - public and private - and the parts share the same key ID and fingerprint. The only real differences in the output for the private key is that the primary key is denoted with 'sec' (secret) to show it is a private key. Likewise, the subkey is denoted with 'ssb' (secret sub) for the same reason.

Referring to keys

For GPG commands that perform operations on the local keyring, keys can be referred to using a couple different methods - key ID or key name. For example:

$ gpg --edit-key 0xE4211AD362149FC8

Will accomplish the same thing as:

$ gpg --edit-key rick@demo.com

Because there is only one key in Rick's keyring that has that UID assigned:

sec   rsa4096/0xE4211AD362149FC8 2016-12-31 [SC] [expires: 2018-12-31]
      Key fingerprint = 86DF 43C5 7A27 9918 E392  CD43 E421 1AD3 6214 9FC8
uid                   [ultimate] Rick Demo <rick@demo.com>
ssb   rsa4096/0xC733B294EEE2AC54 2016-12-31 [E] [expires: 2018-12-31]

If there were multiple keys in his keyring that shared that UID, Rick would need to refer to a specific key by its ID. Key IDs are less convenient to type, but using the key ID is a more accurate way of referring to a key and will give you the most predictable results.

Trust and validity

Key signing and trust assignment are the foundations of GPG's "web of trust." As you add public keys to your keyring, you will assign those keys varying degrees of "trust." Trust as defined by GPG is a measure of your faith in the key's owner to properly validate the identity of UIDs they sign with their own key. These trust settings are then used by GPG to calculate a given UID's "validity," based on your trust in those who have signed that UID.

There are five levels of trust:

  • unknown You don't know anything about the key owner's judgement. This is the default trust for any key you don't own.
  • none The key owner is known to improperly sign other people's keys. Bad dog.
  • marginal The key owner seems to have good judgement and follows best practices when signing keys.
  • full The key owner has a solid handle on key signing, and you trust their judgement.
  • ultimate You are the key owner. Nobody trusts you more than you. And vice versa.

Trust is not a measure of your faith in the authenticity of a particular key, but rather in the judgement of its owner.

As an example, let's say you know three people. Tina, Bob, and Mike. Tina is very thorough in validating the identities of the people for whom she signs keys. Bob just got started with key signing, and you don't yet trust his judgement as much as Tina's. Mike is just a lunatic and randomly signs keys he finds on the Internet. You might assign Tina's key 'full' trust, Bob's key 'marginal' trust, and Mike's key - well, you don't trust that one at all, so 'none'. If you get a key from someone you don't know, you would leave the trust as 'unknown' (which is the default).

As you add people's public keys, some UIDs will be signed by Tina, some by Bob, and some by Mike. Some will be signed by more than one. GPG will perform a calculation of each UID's "validity" based on who has signed the UID and how much you trust the signer. UIDs with Tina's signature will have 'full' validity. UIDs with Bob's signature will have 'marginal' validity. If another person you assign 'marginal' trust also signs the same UIDs as Bob, those UIDs will gain 'full' validity (since two 'marginal' signatures bestows the same validity as one 'full'). The trust calculations can get kind of complicated because there are other factors like path length (degrees of separation) between your key and the subject key.

The most important thing to understand is that trust and validity are relevant only to your own keyring. Other (stupid) people may trust Mike fully, and so the validity of the UIDs that Mike has signed will be calculated as 'full' in their keyrings. Your "web of trust" is really only yours, and you can manage it how you see fit.

Assigning trust to a key in your keyring is pretty straightforward and is done using the --edit-key option. Let's assign trust to Tony Example's key in Rick Demo's keyring:

$ gpg -k

/home/rdemo/.gnupg/pubring.kbx
------------------------------
pub   rsa4096/0xEC837AE765CD8817 2011-09-11 [SC] [expires: 2018-01-01]
      Key fingerprint = 53C1 D387 1842 2B2C 6F28  F9AF EC83 7AE7 65CD 8817
uid                    [unknown] Tony Example <tony@example.com>
sub   rsa4096/0xD152C259D0EFB4D5 2011-09-11 [E] [expires: 2018-01-01]

$ gpg --edit-key 0xEC837AE765CD8817

pub   rsa4096/0xEC837AE765CD8817
      created: 2011-09-11  expires: 2018-01-01  usage: SC
      trust: undefined     validity: unknown
sub   rsa4096/0xD152C259D0EFB4D5 2011-09-11 [E] [expires: 2018-01-01]
      created: 2011-09-11  expires: 2018-01-01  usage: E
[unknown] (1). Tony Example <tony@example.com>

gpg> trust

GPG will now present us with a dialog asking the trust level to assign to the key:

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

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

Your decision? 4

Since Rick knows Tony and knows that Tony is very careful about checking the keys he signs, we'll choose '4' to assign full trust. Now any UIDs in Rick's keyring that have been signed by Tony's key will receive 'full' validity.

Whether to trust other people's keys marginally or fully (or not at all) is a subjective matter, based on how well you know the key owner and their habits of validating the keys they sign. You probably shouldn't give anyone else's key 'ultimate' trust, unless you trust their judgement as much (or more) than you trust your own. And really, not even then. Reserve ultimate trust for your own key(s).

After you assign trust, GPG will print the key again, showing the new trust that has been assigned:

pub   rsa4096/0xEC837AE765CD8817
      created: 2011-09-11  expires: 2018-01-01  usage: SC
      trust: full          validity: unknown
sub   rsa4096/0xD152C259D0EFB4D5 2011-09-11 [E] [expires: 2018-01-01]
      created: 2011-09-11  expires: 2018-01-01  usage: E
[unknown] (1). Tony Example <tony@example.com>

When the new level of trust is assigned GPG automatically re-calculates and updates Rick's trust database, reflecting any changes to the calculated validity of any UIDs signed by Tony on keys already in Rick's keyring. A save of the key is not required, the change in trust takes place immediately.

Publishing your key

Once you have a GPG key pair, you can publish your public key to others in several ways. The easiest is to upload your key to a public PGP keyserver. These public servers sync amongst themselves and provide an easy means of sharing, locating and downloading keys.

To publish your GPG public key, just use the command:

$ gpg --send-keys <key ID>

For example, we can send Rick Demo's public key to the keyservers by doing:

$ gpg --send-keys 0xE4211AD362149FC8

The exact keyserver to which the key is sent is set in the ~/.gnupg/gpg.conf file with the keyserver option:

keyserver hkp://pool.sks-keyservers.net

However, since most keyservers sync their own databases with other keyservers, you only need to upload your key to one keyserver. Within some period of time (minutes to days) your uploaded key will propagate throughout the keyserver network and be available to find if searched for on any of the other servers.

While you may expire or revoke a key sent to the public keyserver network, you cannot remove a key from the database. Be sure your key is correct before sending it to any keyserver.

Another common way to publish a public key is to place the key on a shared network location (file server, web server, Dropbox, etc.) and provide a link to it in on your website, in your email signature, or in your social media profiles. If you do this, be sure to include the full fingerprint for the public key along with the link. This will let others verify that they have the correct key for you.

Finding other people's keys

If you know the key ID for the person's public key, you may download the key and import it using GPG:

$ gpg --recv-keys <key ID>

For example, if Rick wanted to retrieve Tony's public key from a keyserver, he could enter:

$ gpg --recv-keys 0xEC837AE765CD8817

GPG will find the key, retrieve it, and import it into Rick's public keyring.

gpg: key 0xEC837AE765CD8817: public key "Tony Example <tony@example.com>" imported
gpg: Total number processed: 1
gpg:               imported: 1

You may also use gpg --recv-keys to update a specific key already in your keyring, if you know that it's been changed. If you want to update all of the keys in your keyring to the latest version on the keyservers, you can do:

$ gpg --refresh-keys

It's a good idea to do this on a regular basis, to ensure that your keyring gets updated if one of the public keys in it is modified, expired, or revoked.

If you don't know the key ID of the public key you want to download, you may search for it using the command:

$ gpg --search-keys <name>

For example:

$ gpg --search-keys tony@example.com
gpg: data source: http://176.9.147.41:11371
(1)     Tony Example <tony@example.com>
          4096 bit RSA key 0xEC837AE765CD8817, created: 2011-09-11
Enter number(s), N)ext, or Q)uit >

If Tony publishes his key on his website (https://example.com/keys/tony.asc), you can download and import it using the command:

$ gpg --fetch-keys https://example.com/keys/tony.asc

If you'd already downloaded the key to a file on your computer, you could also import it directly:

$ gpg --import tony.asc

After any import operation, view your public keyring (gpg -k) and compare the fingerprint of the imported key with the known fingerprint the owner provided. Make sure you have the correct public key for that person!

Don't just check the key ID, ensure the full fingerprint matches!

Setting a default key

If you have more than one private key in your keyring (e.g., one for work and one for personal) you may want to assign one key as your default. You can set this in the ~/.gnupg/gpg.conf config file with the default-key <key ID> option.

default-key 0x86DF43C57A279918E392CD43E4211AD362149FC8

Signing a message

You digitally sign a file or message with your private key to prove you authored the contents, and that the message has not been altered. GPG has multiple methods of signing, and can produce either binary output or ASCII armored clear text. Most often, we want the latter and we also want to display the original signed text in an unencrypted form.

Let's say Rick has a file named secfile.txt:

$ cat secfile.txt
Mary had a little lamb. I affirm that to be the case. --Rick

Rick is making a sworn statement and wants to prove that the contents of the message are his own, so he signs the document with his GPG private key:

$ gpg --clear-sign secfile.txt

This command produces a new text file named secfile.txt.asc, wherein the contents are now signed:

$ cat secfile.txt.asc
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Mary had a little lamb. I affirm that to be the case. --Rick
-----BEGIN PGP SIGNATURE-----

iQIzBCDECgAdFiEEcNm5c/HxdPhxarvH80P+K+uLYIIFAlnv/c4ACgkQ90P+K+uL
YIJ9Sw//X1mtOeB4CID7wwoinESTcQSIxq14gfXB/OSoBjYJjxH6mpHHE3GBvo/0
1TrY2pihGsmyaCoLqjGz2X4fPcM/29rr6qUX75lHTQvug7yXJNel/ClxS1IOMSy4
7wfutCsjb/yU/Z3TaGaJpKnYxqM1Z3LNhyobJdpn4rM82pUIe3FjGXVJCzLCU/n0
j6jGnpmkMMCqNQcdGMh1uSmdFit1TxbLTeF2pXZcAmBCh9+Qi34YSd36tRHll1bw
F+TUCae10z+1ixPL80OvIg+UQV9ZrBeaerAt6mIK3ntfxNHF6jT6yOGUimbb/PhJ
f/szZI9MxAcDHv3gvbhguVHg9EhKUwovd4dvns1MZMi3SAQ3VVd+NVaVd7jr9w3v
d5HpRNgO4StQc/wGm18K4ROzA8tNueLH+9uZCOQjd3OLS1cxXALiO4h8LuBYh4BN
fG8kKufVzNnOhKbos34ZyCDgnFk6m21xlqWO+OLwjjMtIW5gYotlurbbG/Ww5Byh
eNq20ap648vkw9+HidJqc1S9wJxuh5i5aVHoGDXTXb41bn7y3DZS8KRSeAb6/qAU
l2P0eCpUcP4DVi9HrSKD8FATMunVysvT/MMqSeOQ7lyE7kA5SvXXhuvXxfz0mgdR
fBEMm2YXOUCwpwg5nGlnKgqQBDWLw99IdyT7h1wBXeBHRZvhvy5=
=UQyk
-----END PGP SIGNATURE-----

Verifying a signature

If Rick sends the secfile.asc file to Tony (who has Rick's public key in his keyring), Tony can verify that the message was signed by Rick and has not been altered.

$ gpg --verify secfile.txt.asc
gpg: Signature made Tue 17 Oct 2017 10:58:22 PM EDT
gpg:                using RSA key 86DF43C57A279918E392CD43E4211AD362149FC8
gpg: Good signature from "Rick Demo <rick@demo.com>" [unknown]
Primary key fingerprint: 86DF 43C5 7A27 9918 E392  CD43 E421 1AD3 6214 9FC8

But let's say that Bob in Accounting intercepts Rick's message prior to its delivery to Tony. Bob attempts to alter Rick's sworn statement because he doesn't like Mary, or little lambs:

$ vim secfile.asc
$ cat secfile.asc
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Mary DID NOT have a little lamb. I affirm that to be the case. --Rick
-----BEGIN PGP SIGNATURE-----

iQIzBCDECgAdFiEEcNm5c/HxdPhxarvH80P+K+uLYIIFAlnv/c4ACgkQ90P+K+uL
YIJ9Sw//X1mtOeB4CID7wwoinESTcQSIxq14gfXB/OSoBjYJjxH6mpHHE3GBvo/0
1TrY2pihGsmyaCoLqjGz2X4fPcM/29rr6qUX75lHTQvug7yXJNel/ClxS1IOMSy4
7wfutCsjb/yU/Z3TaGaJpKnYxqM1Z3LNhyobJdpn4rM82pUIe3FjGXVJCzLCU/n0
j6jGnpmkMMCqNQcdGMh1uSmdFit1TxbLTeF2pXZcAmBCh9+Qi34YSd36tRHll1bw
F+TUCae10z+1ixPL80OvIg+UQV9ZrBeaerAt6mIK3ntfxNHF6jT6yOGUimbb/PhJ
f/szZI9MxAcDHv3gvbhguVHg9EhKUwovd4dvns1MZMi3SAQ3VVd+NVaVd7jr9w3v
d5HpRNgO4StQc/wGm18K4ROzA8tNueLH+9uZCOQjd3OLS1cxXALiO4h8LuBYh4BN
fG8kKufVzNnOhKbos34ZyCDgnFk6m21xlqWO+OLwjjMtIW5gYotlurbbG/Ww5Byh
eNq20ap648vkw9+HidJqc1S9wJxuh5i5aVHoGDXTXb41bn7y3DZS8KRSeAb6/qAU
l2P0eCpUcP4DVi9HrSKD8FATMunVysvT/MMqSeOQ7lyE7kA5SvXXhuvXxfz0mgdR
fBEMm2YXOUCwpwg5nGlnKgqQBDWLw99IdyT7h1wBXeBHRZvhvy5=
=UQyk
-----END PGP SIGNATURE-----

Bob sends the message on to Tony in an email with forged headers, claiming to be from Rick. When Tony receives the message and attempts to verify its contents, he discovers that the message was signed by Rick's key but the contents have been tampered with in transit:

$ gpg --verify secfile.asc
gpg: Signature made Tue 17 Oct 2017 10:58:22 PM EDT
gpg:                using RSA key 86DF43C57A279918E392CD43E4211AD362149FC8
gpg: BAD signature from "Rick Demo <rick@demo.com>" [unknown]

Tony cannot determine who exactly modified the message, or what exactly was changed. Only that the message he received was not the original signed message Rick sent.

Encrypting a message

To encrypt a file for someone else to decrypt, you need that person's public key in your keyring. Let's say that Rick has a sensitive document that he wants to send to Tony:

$ cat secret.txt
Tony - I just found out that Mary never even had a little lamb. Keep
this between you and I, the scandal would be damaging. --Rick

Rick suspects that Bob in Accounting is plotting against him, so he encrypts the file so that only Tony's private key can decrypt it. Rick has Tony's public key in his keyring, so he uses the command:

$ gpg -ea -r tony@example.com secret.txt

This creates a new, encrypted file called secret.txt.asc:

$ cat secret.txt.asc
-----BEGIN PGP MESSAGE-----

hQIMAzLTuHCu9C54AQ/9HuHBLdxqUlKH9CQLJ9lzUyUD6WMZIsot0YYP+FgFLxSg
wm/zwHWRS0IXRARrY/0t4B/Lmf1TRTA/3u6Ak/if3uAps2XFgAFWZT2PF0efhnS4
62N6I2DSlODpnxCElu83y0ZZpzDUdjQ6hP7I//146MhNjkbHAdDJNA+NYx/5QdTU
8OuWK414SG2wNnU7Clh7VXTC8HdHHlRU/0UjDvDQwtyh4AKpmbIekbhEm1FuHA+m
DYav3ZrNoNRmY1gM+87Z+fW3KSY5Iw6PlOUUoggCDbiVGb2ugQbjARXc6YE2bsTn
6NHY4Ln8N8gDw2BSjdYZ5uQ0sdeKYpoahmENXht86VokptO/uUixWmIgl/T/kV+I
sIQ86rCs+b3KcIlTE4aREIn8GeR/dkMBGWDHgtEpgVk8vbH3cF88Xy6OnOwkG6Dc
6/Br0uSJuqXJBXYwSo+6YHE6b2YMUIYcpWhvm0dBlefimgcPDXybB66ws9DRRYf/
14W7aXj42klYf229BNFXL2LTsxHDR9a0gHbpmV82GV2i9TZaSLX/d3oRAJ/3+GfA
3EWfG5A55Cn0EO4m8DZCg5lUd5AGLE+862BPwpqHMh3UJ+7VrR+r9TLJ6Wjh3Ajh
btrMa+3beOt5v4HFMVq+8sikyhgO4XE4uTiyMW0/3k9ELEmBK+aTuFBQW3vZaBrS
WAEuI8OQWIXMpAVoCdgtq8lleLPF5qyf+a75nXfF9lSabWYpNM/3dVGpooYv7+Nx
nBqJWw/MN5oq1U/pHq4rYhvrRHtyMgswnU42MY9WPUFISdrlfQ/0P3Q=
=eMPZ
-----END PGP MESSAGE-----

If Bob intercepts this file, he cannot read the contents of the message.

Typically when we encrypt files to others, we also sign the message with our own GPG private key. To sign and encrypt at the same time, use the command:

$ gpg -sea -r <recipient@domain.tld> <filename>

Observe the use of -s in addition to -e. When you sign and encrypt your message, you will be prompted for your private key password. Encryption alone doesn't use your private key (only the recipient's public key).

When you sign and encrypt, the signature itself becomes encrypted. Only the recipient can --verify the signature on the message, and only after the message has been decrypted. This is by design. If a message is intercepted (in absence of email headers or other identifying marks) there is no way for the intercepting party to know who created the message, or for whom it was intended.

Decrypting a message

To decrypt a message that has been sent to you, simply run the command:

$ gpg -d <filename>

GPG will prompt you for your private key passphrase, then decrypt and print the file contents, and verify any signatures that are on the file. If you want to save the decrypted contents to a new (unencrypted) file, specify an output (-o) filename with the command:

$ gpg -d -o output.txt secfile.txt.asc

Updating your key's expiration date

Whenever you create a GPG key pair, you are given the option to set an expiration date on the keys. Many people don't do that because they think, "I don't want my keys to expire!"

Actually, you do.

Expiration dates on GPG keys are not like expiration dates on dairy products. GPG key expiration dates can be extended by the owner at any time. The purpose of the expiration date is to serve as a failsafe mechanism in the event that you were to lose access to your private key and not be able to revoke the public key. If not updated, your key will eventually expire and people who have your key in their keyring (or who search for the key on a keyserver) will know not to use that key.

As long as you have access to the private key, you may extend your key's expiration date indefinitely. Also, if a key expires (intentionally or accidentally) it does not invalidate the public key. If you forget to extend the expiration date on your key and it expires, you can still change the expiration date and revalidate the key, provided you have access to the private key. Obviously, if you are actively using your GPG keys you don't want them to remain expired for an extended period, but it is not a crisis if you forget and the key expires for a short time.

I can think of no situations where you might regret putting an expiration date on a key, and I know of a few cases where you would definitely regret not doing it.

And it's really easy to do:

$ gpg --edit-key <key ID>
gpg> expire
Changing expiration time for the primary key.
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)

Select the expiration period you would like for your key. Generally, this should be kept reasonably short - as in 6 to 12 months. If you use an offline primary key and online subkeys (see One GPG key pair (to rule them all)), you may want to set a longer expiration on the primary key (2 or 3 years, for example) and a shorter expiration on the subkeys (6 or 12 months).

After you set your expiration date, you will be prompted for the passphrase for your private key. Then save the change, check that the expiration date is what you expect (if not, repeat the process), and finally upload the key to the keyservers.

gpg> save
$ gpg -k <key name>
$ gpg --send-keys <key ID>

Anyone who has your key in their keyring will get the updated expiration date when they --refresh-keys. If you've published your key in other places (like your website), then also export a copy to replace the one you've previously published.

The "right" length of time for key expiration is much debated and very subjective. The expire length is in some ways a reflection of a person's confidence in their own ability to maintain the integrity of their private key (and their tolerance for risk should that key be lost). If you can absolutely guarantee that your private key will never be lost or stolen, then you don't need to set an expiration date for your key. Unfortunately, most of us are not in that privileged position of absolute certainty - so set a reasonable expiration date on your keys. If you decide later that the length you picked was too long or too short, you can always change it.

Changing your private key passphrase

First off, you should absolutely have a passphrase on your private key. Many people regard it as inconvenient to have to enter a passphrase each time you use your key (hint: that's why we have gpg-agent). But it is much more inconvenient when your private key gets stolen and used inappropriately because it was a "bearer instrument" with no passphrase securing it. Storing your private key in a secure location is your first line of defense. Having a passphrase on it is your last line of defense.

Generally you will set a passphrase on your private key when you create it with gpg --gen-key but should you ever need to change your passphrase, it's a simple procedure:

$ gpg --edit-key <key ID>
gpg> passwd
[prompt for current passphrase, if set]
[prompt for new passphrase]
gpg> save

You may have noticed that throughout this text I generally use the term 'passphrase' and not 'password'. The two are interchangeable in practice, but have very different levels of security. A password might be 'fidelity' or '1fidelity#'. Passwords that are easy to remember also tend to be easy to guess, particularly if the password is a dictionary word. Passwords like 'dF8wMM02jd$@fg!23aP' are much harder to guess - but good luck trying to remember something like that. Passphrases are phrases that are easy to remember, but are difficult to guess because of the complexity added by stringing multiple words together. A passphrase like 'commitment to providing #1 service excellence' is much easier to remember than 'dF8wMM02jd$@fg!23aP' and as it turns out, is much much harder to guess through brute force attacks.

Exporting keys

You may occasionally need to export a public key from your keyring in order to publish the file online or to provide to someone else. To export your key to a file, use the command:

$ gpg --export -a -o <file> <key name>

For example, Rick Demo might his export his key to rick.demo.pub.asc using the command:

$ gpg --export -a -o rick.demo.pub.asc rick@demo.com

You can also export your private key (for example, to make a backup) using the command:

$ gpg --export-secret-keys -a -o <file> <key name>

If you want to export subkeys rather than the primary key:

$ gpg --export-secret-subkeys -a -o <file> <key name>

If you have an authentication subkey in your key pair (capability [A]) you can export that key in OpenSSH public key format:

$ gpg --export-ssh-key -o <file> <key name>

The output can then be added to the authorized_keys file on a host to allow SSH login via public key.

Deleting keys

If you have keys in your keyring that you no longer need, you can remove them with the command:

$ gpg --delete-keys <key name>

For example, if Rick no longer needed Tony's public key he could use the following command to remove it:

$ gpg --delete-keys tony@example.com

You can also delete private keys from your keyring, if for example you no longer use a particular key or if you want to store the private key offline for added security. To do this, use the command:

$ gpg --delete-secret-keys <key name>

Once deleted, you cannot "undelete" a key, but you can re-import it. Before you delete a private key, always be sure to export a copy and save it in a secure place. This way you will have a means to recover the key in the event that you might ever need it again in the future.

Key signing

When you sign a UID on someone else's public key with your private key, you are vouching for the authenticity of the key and the identity of its owner - with your own reputation. This should not be an action taken likely. People who trust your key will place trust in the identities your key has signed. Through this process we establish what is called a "web of trust".

Before you sign a UID on someone else's public key, you should always verify the owner's identity by:

  1. knowing the owner personally, or
  2. verifying the owner's identification through one (or more) forms of government-issued ID.

You'll typically hear the signing process called "signing the key" - but that is really a sort of shorthand. In reality, you don't directly sign someone else's public key. Instead you sign a UID (identity, name and email) on the key, in effect stating that you have verified that person's identity and that they are a valid holder of that particular key. This an important distinction because a key may have multiple UIDs, and you should only sign the identity or identities that you have personally verified.

Prior to signing a key, you should also verify the authenticity of the public key by comparing the key ID, key type (RSA/DSA), key length (2048/4096), and fingerprint of the key that you are about to sign, to the key information that the owner has provided to you and affirmed is theirs. This information should be generated on the computer where their GPG private key is stored - not derived from a copy of the public key (i.e., downloaded from a keyserver or URL). Ideally, this information should be provided to you in person.

The key signing process itself is not difficult, but it can be somewhat logistically challenging due to the verification requirements.

Key signing is often done at "key-signing parties" held at industry conferences, conventions, linuxfests, etc. Each attendee brings with them slips of paper on which their GPG key ID, key type, key length, fingerprint, name, and email address are printed. They also bring their government-issued ID, or anything else that would positively establish their identity. Different signers may require different degrees of identity verification. For example, getting your key signed at DEFCON may be more involved than at your local computer club meetup.

During the key-signing party, attendees trade slips of paper and verify each other's ID. After the function, the attendees take the slips they have received home with them, download the keys with the provided information, sign the keys with their own private key, and then send the signed key to the key owner (at the email address on the slip). As an extra measure of security, the signed key is encrypted with the recipient's public key, so that only the person who has the private key may use the signed public key.

The recipient receives the signed key, decrypts it, and then imports the signed key into their public keyring. Finally, the recipient uploads their signed public key to the keyserver network (or publishes it using whatever other method(s) they prefer) to update the publicly visible signatures on the key.

Signing someone else's key

To sign someone's key, you must first import their key into your public keyring. You may do this using the --recv-keys option if you know the key ID, or with --search-keys to find the key on a keyserver, or you can --import the public key from a file:

$ gpg --search-keys <user@domain.tld>
$ gpg --recv-keys <key ID>
$ gpg --import <key file>

Once you have the key in your keyring, print its fingerprint.

$ gpg --fingerprint <user@domain.tld>

Carefully compare the key ID, key type and length, and the fingerprint of the public key to the information provided to you by the owner. If they do not match exactly, do not proceed. Assuming that everything does match, you may then sign one or more UIDs on the key:

$ gpg --sign-key <user@domain.tld>

GPG will ask you for confirmation before applying the signature, and then prompt you for your private key passphrase.

Now you need to export the signed public key so you can send it to the owner:

$ gpg --export -a -o user.domain.tld.asc <user@domain.tld>

Encrypt that file to the recipient using their public key:

$ gpg -ae -r <user@domain.tld> -o user.domain.tld.enc.asc user.domain.tld.asc

Finally, all that's left to do is to send the key owner the encrypted signed key. You can do this by sending an email to the address in the UID, with the encrypted file as an attachment.

Technically, you can send a signed public key directly to a keyserver yourself using gpg --send-keys, rather than sending the signed copy back to the owner. If you downloaded the key from a public keyserver - and if the owner explicitly told you to upload it after it was signed - then this may be appropriate. Barring that, it's probably a better idea to send the signed key back to the key owner directly. For one, it lets them know that you signed it. It also provides a second layer of verification by sending the encrypted copy of the signed key to the address in the UID, thus ensuring the address is valid and the person at that address holds the private key. Lastly, it gives the key owner control over the distribution of their own key - some people choose not to use the public keyservers. As a cardinal rule, if you didn't download the public key from a keyserver then don't upload the signed key to a keyserver.

Applying signatures to your own key

If someone else has signed your public key, they'll send you an encrypted signed copy of your key. Just decrypt the attachment, import the signed public key, and then upload your key to the keyserver network.

$ gpg -d -o user.domain.tld.asc user.domain.tld.enc.asc
$ gpg --import user.domain.tld.asc
$ gpg --send-keys <key ID>

Revoking your key

When you first create your GPG key pair, you should create a revocation certificate for the complete key. This certificate serves as the emergency kill switch for your GPG public key should your private key ever be lost or compromised, or if you forget the passphrase for the private key. Revoking a key marks the key as no longer valid, and after you publish the revoked key to the keyserver network the key will become marked as revoked in the public database. Anyone searching for that key will see that the key is no longer valid.

The use of the revocation certificate does not require possession of the private key itself! Anyone who can access the revocation certificate may revoke the public key. For this reason, you must keep your revocation certificate secure. But also note that for obvious reasons, full access to the GPG private key is required to generate a revocation certificate. You cannot generate a revocation certificate after you've lost your secret key. Create the revocation certificate before you need it.

If you have never created a revocation certificate you can do so using the command:

$ gpg --gen-revoke <name>

For example, to create a revocation certificate for Rick Demo's key, we would use the command:

$ gpg --gen-revoke -o rick.demo.rc.asc rick@demo.com

sec   rsa4096/0xE4211AD362149FC8 2016-12-31 Rick Demo <rick@demo.com>

Create a revocation certificate for this key? (y/N) 
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?

GPG will ask you to confirm, and then let you provide a reason for the revocation. If you are revoking a key intentionally under planned circumstances, you may answer 2 or 3 if they apply. For your emergency revocation certificate, answer 1 (since that would likely be the circumstance under which you would use it). You will then be prompted for the private key password.

The command will produce ASCII armored output that will be saved into a file. Keep the file in a secure location (preferably, stored offline on an encrypted file system or even printed out on paper and stored in a fire-proof safe).

Generating the revocation certificate itself does not revoke the key. To perform the revocation, you must first import the certificate into a keyring that contains the public key, and then publish the revoked key. Rick's revocation certificate is stored in the file rick.demo.rc.asc. To revoke his public key, we would do this:

$ gpg --import rick.demo.rc.asc

And then upload the revoked public key to the keyserver network:

$ gpg --send-keys 0xE4211AD362149FC8

After synchronization takes place, the public key will be marked as revoked in the database.

If you mistakenly revoke a public key in your keyring, your cannot "unrevoke" it. You can however, delete the key from your keyring and then re-import the public key from a backup or keyserver. This will work provided you have not already uploaded the key to the keyserver network. Once a revoked key is published, there is no way to remove the revoked key from the database. You will have to generate a new key pair.

The three rules of revocation:

  1. Always keep a revocation certificate for your key on file.
  2. Before you revoke a key - be sure that's really what you want to do.
  3. Before you upload a revoked public key - be really, really sure.

Now go encrypt something

While certainly not definitive on the subjects of either GPG or cryptology in general (which are both hugely complex topics), I hope this primer has given you the tools to get started securing your data with GPG. You should now be armed with the knowledge to perform the most common GPG tasks of signing, encrypting, and managing keys.

If you'd like more information about GPG, there are online resources such as the GnuPG Manual and the GnuPG FAQ.

If you're ready to take the next step and create GPG keys of your own, be sure to check out One GPG key pair (to rule them all) to learn how to create a secure primary GPG key with subkeys.