Home
Got Linux ?

Blah blah blah... Mostly technical thoughts, rants and gibberish


GnuPG - A (most certainly outdated) Primer

Courtesy of Idiap (which I originally wrote this primer for, circa 2017) [UPDATED 2021.04.16]

Prologue

[ADDED 2021.04.16]

If you want to piss me off or start me on the wrong foot, just mention GnuPG to me. While I come nowhere close to have the technical knowlege to doubt its cryptographic foundations and internals, I certainly lack the mental agility to cope with its (proper) use, from initial setup to everyday operations.

Some despise OpenSSL for its cumbersome, pre-Cretacea CLI and API. I despise GPG for its open doors to misconfiguration and misuse.

!!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!!

This primer is certainly out-dated, incomplete, erroneous, misleading and plagued by uninformed choices detrimental to security!!! Use it at your own risk!!!

!!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!! WARNING !!!

[BACK TO ORIGINAL CONTENT]

Introduction

There are several reasons why you may want to use PGP/GnuPG encryption or signature, such as:

Before jumping in to generate your PGP/GnuPG keys, please read this primer completely.

Documentation and Training

Using cryptography for encryption/signature implies serious purposes and security concerns.

Security is no stronger than the weakest link in the chain. Thus, naively using cryptography can lead to having a link - and the overall security - no stronger than air. One should therefore get acquainted and become familiar with the main aspects of the cryptographic systems at hand before using them. Failure to do so may lead to catastrophe, as far as the initial purposes are concerned (one notorious such catastrophe was the Debian OpenSSL Blunder, in 2008, which led to massive havoc in the Linux IT world).

As opposed to SSL certificates delivered by well-known (and trained) Certification Authorities, PGP/GnuPG allows (requires!) each user to toss even the most critical parameters of the system (cryptographic algorithms, key sizes, expiration dates, etc.). It is therefore even more important that one MUST get acquainted and become familiar with the key aspects of PGP/GnuPG before messing with it.

PGP/GnuPG Theory

Asymmetric (aka. Public/Private key) Cryptography

PGP/GnuPG relies on asymmetric cryptography where each key(pair) is made of private key and a public key.

In asymmetric cryptography, the private key is used to perform a cryptographic operations - e.g. encryption or signature - that can be reversed only with the public key (or vice-versa).

In practice, this means Alice will:

There is no harm in anyone having Alice’s public key. However, under no circumstances, should Mallory (an attacker), or anyone else, get hold of Alice’s private key.

PGP/GnuPG Primary vs Sub Keys

While SSL certificates (for web server or S/MIME) are always linked to a well-known Certitification Authority, PGP/GnuPG allow each user to be its own “certification authority” by:

For the sake of conciseness, we’ll use the word key to refer to all public keys associated with a given primary key and all its sub keys. When private keys are concerned, we’ll always use the words private key or key(pair) to avoid any possible confusion about their usage.

Private Keys are SECRET !

The most important thing to understand/remember/enforce when using asymmetric cryptography is:

PRIVATE KEYS MUST BE KEPT SECRET !

Therefore, you MUST make sure NO one can read your private keys, by setting appropriate file permissions (chmod 600) on all related material and protect them by a passphrase. Keep in mind that remote storage or shared devices can have their access control to files more easily compromised (than a private device) and can not be ultimately trusted.

You SHOULD (really!) protect private keys with a strong passphrase. And you SHOULD update this passphrase at least once a year. In particular, this will allow PGP/GnuPG to update the encryption scheme used to protect your private keys against brute-force attacks.

Given the purpose of primary key(pair)s, one MAY consider removing primary private keys from the system - and keeping them somewhere really safe - once all necessary sub key(pair)s have been generated. This is particularly true for systems that may be stolen (e.g. portable devices) or can not be ultimately trusted.

COMPROMISED PRIVATE KEYS MUST BE REVOKED !

Should you fear that a private key has been compromised (stolen), you MUST immediately revoke it - using the revocation certificate created for that purpose - and inform your contacts about it. This is true even if you have used a very strong passphrase (which may also be compromised, if nothing by time itself, considering the possibility of brute-force attacks).

PGP/GnuPG Key Validation and Web of Trust

When using asymmetric cryptography, one MUST verify the keys used are the legitimate/expected ones. Failure to do so opens the door to eavesdropping or impersonation.

With SSL certificates, verification is automatically achieved thanks to the trust implicitly given to the Certification Authorities root certificates installed by the vendors (Microsoft, Debian, Mozilla, etc.) on your devices, first link of the so-called Chain of Trust.

Things are not so simple when using PGP/GnuPG. In practice, Bob MUST manually verify the fingerprint of the key he received from Alice, via a separate channel (different from the one used to transmit the key). The most secure way to do so is with a phone call; another way, although less secure, is for Alice to publish the fingerprint of her key(s) on her personal web page, which Bob (and anyone) can visit. Once such verification has taken place and in order to automate further verification of keys by other people, Bob MAY choose to validate the (verified!) keys he received and publish this validation to key servers for the sake of other users. Those other users MUST then decide whether - and how much - they trust Bob to perform this verification/validation process, leading to PGP/GnuPG so-called Web of Trust.

Please do NOT contribute to PGP/GnuPG Web of Trust until you fully understand all aspects of the recommended best practices below. Erronously validating keys and being mistakingly trusted by others forfeits the entire purpose of the Web of Trust.

Recommended Best Practices

Much has changed since the onset of PGP/GnuPG and one should be wary of obsolete recommendations. [AS OF 2017] Even the official GnuPG user guide is outdated compared to the current widely accepted best practices (it is this ascertainment that prompts us to write this primer rather than point you directly to the official documentation).

The PGP/GnuPG recommended best pratices given below MUST be regularly reviewed/revisited (as would the recommended best practices for any other cryptographic system).

We will go through each of those in the order in which questions will be asked when using the GnuPG utility to generate keys.

Algorithms and Key Sizes

The official GnuPG user guide recommends DSA and ElGamal as algorithm choices.

Those were good choices in 1999 but certainly not any longer, with computing power increasing and vulnerabilities creeping in.

[UPDATED 2021.04.16] Nowadays (2021), one SHOULD opt for:

Key(pair)s Capabilities (Purposes)

PGP/GnuPG allows each key(pair) to be associated with the following capabalities/purposes:

Nowadays (2017), one SHOULD:

By using the primary key(pair)s for no other purpose than certifying sub key(pair)s and identities, one may remove the primary private keys from marginally-trusted systems without affecting PGP/GnuPG common/daily operations.

As for having a sub key(pair)s dedicated to each purpose:

Key(pair)s Expiration

The official GnuPG user guide invites us to set key(pair)s to never expire.

This is now considered very bad practice! If, for whatever reason, a key(pair) is lost (or forgotten about; yes! this can happen, especially with first-time or casual users), there will be no mechanism to automatically invalidate the given key(pair) which, if published to a key server, will remain accessible and usable until the end of time.

[UPDATED 2021.04.16] Nowadays (2021), you SHOULD set expiration date on your generated key(pair)s:

Associated Identities

PGP/GnuPG mandates that you associate at least one identity - one’s full name and e-mail address - to a given key. But it also allows to associate multiple identities to the same key.

While this can prove useful in certain circumstances - like having a long, fully qualified e-mail address and a shorter, loginname-like one, corresponding to the same individual, within the same organization - it is a bad practice and one SHOULD NOT associate to a given key identities that are not about the same organization or purpose. In particular, one SHOULD NOT (really!) associate one’s professional (alice@example.org) and private identity (al@example.net) to the same key.

Backups and Revocation

You SHOULD NOT use - especially more so, publish - keys unless you have:

Failure to do so:

About Key IDs and Fingeprints

Each PGP/GnuPGP key can be identified using:

In an ideal world, one ought to use the fingerprint to identify keys univocally. Unfortunately, humans are not so comfortable when dealing with long strings of random data. It is therefore much easier to use keys IDs or identities, although they might end up equivocal.

Nowadays (2017), one MUST be aware that 8-char IDs or associated identities may lead to the wrong key - e.g. when being fetched from a key server - since:

Therefore, one SHOULD use:

GnuPG (version 2) in Practice

When going through the command line samples below, please bear in mind that only significant input/output is showed, for the sake of conciseness and clarity.

[MUST] Generate the Primary Key(pair)

$ gpg --expert --full-generate-key
Please select what kind of key you want:
  (8) RSA (set your own capabilities)
Your selection? 8

Possible actions for a RSA key: Sign Certify Encrypt Authenticate
Current allowed actions: Sign Certify Encrypt
  (S) Toggle the sign capability
  (E) Toggle the encrypt capability
  (A) Toggle the authenticate capability
  (Q) Finished
Your selection? S
Your selection? E
[Current allowed actions: Certify]
Your selection? Q

What keysize do you want? (3072) 4096

Please specify how long the key should be valid.
  <n>y = key expires in n years
Key is valid for? (0) 5y

Real name: Alice - Example Organization
Email address: alice@example.org
Comment: [[ e.g. "Key to be used specifically for project XYZ" ]]

[[ eventually ]]

pub   rsa4096 2021-04-16 [C] [expires: 2026-04-15]
      <ID0-fingerprint>
uid   Alice - Example Organization <alice@example.org>

Note the <ID0> of your key(pair); this ID is used by PGP/GnuPG to identify it.

[SHOULD] Generate Sub Key(pair)s

$ gpg --expert --exit-key ${ID0}

[[ create sub key(pair) for signature (only) ]]

gpg> addkey
You need a passphrase to unlock the secret key for
user: "Alice - Example Organization <alice@example.org>"
4096-bit RSA key, ID <ID0>, created 2017-06-23

Please select what kind of key you want:
  (8) RSA (set your own capabilities)
Your selection? 8

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt
  (S) Toggle the sign capability
  (E) Toggle the encrypt capability
  (A) Toggle the authenticate capability
  (Q) Finished
Your selection? E
[Current allowed actions: Sign]
Your selection? Q

What keysize do you want? (3072) 2048

Please specify how long the key should be valid.
  <n>y = key expires in n years
Key is valid for? (0) 1y

[[ eventually ]]

sec  rsa4096/<ID0-16char>
     created: 2021-04-16  expires: 2026-04-15  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa2048/<ID1-16char>
     created: 2021-04-16  expires: 2022-04-16  usage: S
[ultimate] (1). Alice - Example Organization <alice@example.org>

[[ create sub key(pair) for encryption (only) ]]

gpg> addkey
You need a passphrase to unlock the secret key for
user: "Alice - Example Organization <alice@example.org>"
4096-bit RSA key, ID <ID0>, created 2017-06-23

Please select what kind of key you want:
  (8) RSA (set your own capabilities)
Your selection? 8

Possible actions for a RSA key: Sign Encrypt Authenticate
Current allowed actions: Sign Encrypt
  (S) Toggle the sign capability
  (E) Toggle the encrypt capability
  (A) Toggle the authenticate capability
  (Q) Finished
Your selection? S
[Current allowed actions: Encrypt]
Your selection? Q

What keysize do you want? (3072) 3072

Please specify how long the key should be valid.
  <n>y = key expires in n years
Key is valid for? (0) 3y

[[ eventually ]]

sec  rsa4096/<ID0-16char>
     created: 2021-04-16  expires: 2026-04-15  usage: C
     trust: ultimate      validity: ultimate
ssb  rsa2048/<ID1-16char>
     created: 2021-04-16  expires: 2022-04-16  usage: S
ssb  rsa3072/<ID2-16char>
     created: 2021-04-16  expires: 2024-04-15  usage: E
[ultimate] (1). Alice - Example Organization <alice@example.org>

gpg> save

[MAY] Show the Generated Key(pair)s

$ gpg --keyid-format long --list-keys ${ID0}
pub   rsa4096/<ID0-16char> 2021-04-16 [C] [expires: 2026-04-15]
      <ID0-fingerprint>
uid                 [ultimate] Alice - Example Organization <alice@example.org>
sub   rsa2048/<ID1-16char> 2021-04-16 [S] [expires: 2022-04-16]
sub   rsa3072/<ID2-16char> 2021-04-16 [E] [expires: 2024-04-15]

$ gpg --keyid-format long --list-secret-keys ${ID0}
sec   rsa4096/<ID0-16char> 2021-04-16 [C] [expires: 2026-04-15]
      <ID0-fingerprint>
uid                 [ultimate] Alice - Example Organization <alice@example.org>
ssb   rsa2048/<ID1-16char> 2021-04-16 [S] [expires: 2022-04-16]
ssb   rsa3072/<ID2-16char> 2021-04-16 [E] [expires: 2024-04-15]

[MUST] Generate the Revocation Certificate

In case you primary private key gets compromised, you MUST be able to revoke it.

[UPDATED 2021.04.16] Latest versions of GnuPG creates the revocation key at the time primary key(pair) is generated (see above):

gpg: revocation certificate stored as '~/.gnupg/openpgp-revocs.d/<ID0-fingerprint>.rev'

Please move it to a medium which you can hide away; if Mallory gets access to this certificate he can use it to make your key unusable. It is smart to print this certificate and store it away, just in case your media become unreadable. But have some caution: The print system of your machine might store the data and make it available to others!

[MUST] Backup all Key(pair)s

There is no procrastinating about it: you MUST secure you PGP/GnuPG material on a media kept safely offline/offsite:

To export you key(pair)s

[[ export the private keys of the primary key(pair) and all sub key(pair)s ]]

$ touch sec.asc && chmod 600 sec.asc && gpg --export-secret-keys --armor ${ID0} > sec.asc

[[ export the public keys of the primary key(pair) and all sub key(pair)s ]]

$ gpg --export --armor ${ID0} > pub.asc

[MAY] Remove the Primary Private Key

WARNING: Make sure to have it backed-up beforehand (see above)! You will need to (re-)import it to edit the associated sub key(pair)s!

Also note that validating other people keys - be it for your own local trust purposes or for contributing to PGP/GnuPG Web of Trust - requires you keep the primary private key handy.

$ touch ssb.asc && chmod 600 ssb.asc && gpg --export-secret-subkeys --armor ${ID0} > ssb.asc

$ gpg --delete-secret-keys ${ID0}

$ gpg --import ssb.asc

[AS REQ’D] I got it Wrong…

You may need a few tries before getting your PGP/GnuPG setup right. This is no problem at all, provided:

To undo all you just did:

$ gpg --delete-secret-and-public-keys ${ID0}

[MAY] Publish your Key(s)

WARNING: THIS OPERATION IS NOT REVERSIBLE !

Once you got everything right, you MAY consider publishing your public keys to so-called key server(s), for other users to easily get hold of them. Note that is not mandatory; you may prefer to distribute your keys by e-mail, a personal web page, etc. On the other hand, key servers have the benefit of being a distribution channel de facto separate from the ones you commonly use PGP/GnuPG for (e-mails, files download via the web, etc.) and also are the corner-stone of PGP/GnuPG Web of Trust.

WARNING (repeat!): Once keys have been published to a key server, they CAN NOT be unpublished. EVER! (they can only be updated/revoked)

$ gpg --keyserver keys.gnupg.net --send-keys ${ID0}

[MAY] Obtain Someone Else Key(s)

$ gpg --keyserver keys.gnupg.net --recv-keys ${IDx}

[MUST] Show and Verify the Fingerprint of a Key

$ gpg --fingerprint ${IDx} [OR] gpg --fingerprint ${identity}
pub  4096R/<IDx>  created: 2017-06-23  expires: 2022-12-31  usage: C
    <IDx-fingerprint>
uid  [ unknown] Bob - Example Organization <bob@example.org>

[SHOULD] Validate a Key

Once you have verified the fingerprint of a key, you SHOULD validate it to signify your own trust, either locally (lsign) for your own purposes or globally (sign) to contribute to PGP/GnuPG Web of Trust.

$ gpg --edit-key ${IDx} [OR] gpg --edit-key ${identity}
gpg> lsign [OR] sign (once you fully understands PGP/GnuPG Web of Trust issues)
pub  4096R/<IDx>  created: 2017-06-23  expires: 2022-12-31  usage: C
                  trust: unknown       validity: unknown
Primary key fingerprint: <fingerprint>
    Bob - Example Organization <bob@example.org>

Are you sure that you want to sign this key with your
key "Alice - Example Organization <alice@example.org>" (<ID0>)
Really sign? (y/N) y

gpg> save

If validating the key globally (sign) and willing to contribute to PGP/GnuPG Web of Trust, you MAY then re-publish the key - along your newly-added signature - to the key server(s):

$ gpg --keyserver keys.gnupg.net --send-keys ${IDx}

[MAY] Trust a Key Owner

Once you have verified the fingerprint of a key, you MAY trust its owner to validate other people public keys.

$ gpg --edit-key ${IDx} [OR] gpg --edit-key ${identity}
gpg> trust
pub  4096R/<IDx>  created: 2017-06-23  expires: 2022-12-31  usage: C
                  trust: unknown      validity: full
sub  2048R/<IDy>  created: 2017-06-23  expires: 2018-12-31  usage: S
sub  3072R/<IDz>  created: 2017-06-23  expires: 2020-12-31  usage: E
[  full  ] (1). Bob - Example Organization <bob@example.org>

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? [your call!]

gpg> save

[AS REQ’D] Change a Key Passphrase

$ gpg --edit-key ${ID0}
gpg> passwd
You need a passphrase to unlock the secret key for
user: "Alice - Example Organization <alice@example.org>"
4096-bit RSA key, ID <ID0> created 2017-06-23

Enter the new passphrase for this secret key.
[...]

gpg> save

Note: as PGP/GnuPG utilities get updated, they will improve the default scheme used to encrypt the private keys (see the --s2k-* parameters). You SHOULD thus perform this operation at least sporadically, even if keeping the same (hopefully very strong) passphrase.

[AS REQ’D] Revoke a Compromised Key

WARNING: THIS OPERATION IS NOT REVERSIBLE !

[[ see above for how to generate the revocation certificate ]]

$ gpg --import rev.asc

$ gpg --keyserver keys.gnupg.net --send-keys ${ID0}

[SHOULD] A Sensible Defaults Configuration (to get you started)

cat > ~/.gnupg/gpg.conf << EOF
## GnuPG defaults settings

# Show the long (16-char) key IDs <-> deter short (8-char) key IDs collision
# REF: gwolf.org/node/4070
keyid-format 0xlong

# Default key ID to use for key validation/signature
# (if having several primary key(pair)s configured)
default-key ${ID0}

# Nowadays, we live in a UTF-8 world
charset utf-8

# A sensible key server to use
# (note that most well-known key servers are synchronized one-with-another)
keyserver keys.gnupg.net
EOF

[MAY] Advanced Usage

By using the gpg --list-packets, you can obtain detailed/advanced information on many PGP/GnuPG output.

$ gpg --export-secret-keys ${ID0} | gpg --list-packets
:secret key packet:
version 4, algo 1, created 1498730514, expires 0
skey[0]: [4096 bits]
skey[1]: [17 bits]
iter+salt S2K, algo: 9, SHA1 protection, hash: 8, salt: d135004746d90597
protect count: 1015808 (159)
protect IV:  71 7e b4 46 f6 8a 02 5e 83 bc 5c f2 21 ba 98 f0
encrypted stuff follows
keyid: <ID0>
    :user ID packet: "Alice - Example Organization <alice@example.org>"
    :signature packet: algo 1, keyid <ID0>
version 4, created 1498730514, md5len 0, sigclass 0x13
digest algo 8, begin of digest 58 80
hashed subpkt 2 len 4 (sig created 2017-06-29)
hashed subpkt 27 len 1 (key flags: 01)
hashed subpkt 9 len 4 (key expires after 5y0d0h0m)
hashed subpkt 11 len 6 (pref-sym-algos: 9 8 7 3 2 1)
hashed subpkt 21 len 5 (pref-hash-algos: 8 2 9 10 11)
hashed subpkt 22 len 3 (pref-zip-algos: 2 3 1)
hashed subpkt 30 len 1 (features: 01)
hashed subpkt 23 len 1 (key server preferences: 80)
subpkt 16 len 8 (issuer key ID <ID0>)
data: [4093 bits]

[[ e.g. we can see here the private key is protected against brute-force by a proper,
   salted and highly iterated, key derivation function (string-to-key, S2K) ]]

[SHOULD] Therefrom…

Now that you have keys created as per todays (2017) recommended best practices, you can go on using PGP/GnuPG as per the official user guide.

[MAY] And ultimately…

$ man gpg

Using PGP/GnuPG in Other Applications

Thundebird / Enigmail

PGP/GnuPG integrates seamlessly with Thunderbird thanks to the Enigmail extension (pre-installed on Idiap workstations).

Every key operation you carry out on the command line will be reflected in Thunderbird/Enigmail and vice-versa. However, carrying out sensitive operations - like keys management - is better achieved on the command line, since it offers more options and a better control.

In order to use PGP/GnuPG, you MUST edit your Account Settings and make sure the OpenPGP Security configuration meets your requirements.

Mac OS X

The GPG Tools project provides the original GnuPG command line utility along GUI add-ons that makes using PGP/GnuPG on Max OS X and its default e-mail client (Mail) as easy as it gets.

It’s all too Complicated!

If you feel this is all too complicated, then look into S/MIME (SSL certificates used for e-mail encryption and digital signatures). When using S/MIME, 90% of the critical stuff we just covered (cryptographic algorithms, capabilities, key sizes, expiration dates, revocation, trust issues, etc.) is taken care for you by issuing companies (by properly trained staff).

Acknowledgments

Thanks to my fellow colleagues for their reading and corrections of this primer:

References

Epilogue

[ADDED 2021.04.16]

Bah! Why do I complain? This ain’t so complicated, afterall…