Courtesy of Idiap (which I originally wrote this primer for, circa 2017) [UPDATED 2021.04.16]
[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]
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.
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 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:
keep her private key secret
publish/transmit her public key to anyone of her contacts; e.g. Bob
such as to allow Bob to:
use her public key to encrypt messages sent to her, which she will be able to decrypt (only) using her private key
use her public key to verify the authenticity and integrity of her messages, signed with her private key
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.
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:
having each user create a primary key(pair) (corresponding to SSL’s root certificate)
and several sub key(pair)s, linked to the former (corresponding to SSL’s servers or individuals certificates)
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.
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).
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.
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.
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:
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:
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:
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.
You SHOULD NOT use - especially more so, publish - keys unless you have:
Failure to do so:
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:
cedric.dufour@idiap.ch
key on any key server (e.g. http://keys.gnupg.net) should you need proof for
the above claim, at the author’s expense… the 1024D/E447BCAD
key is genuine, the
1024R/E447BCAD
is FAKE!)Therefore, one SHOULD use:
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.
$ 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.
$ 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
$ 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]
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!
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
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
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}
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}
$ gpg --keyserver keys.gnupg.net --recv-keys ${IDx}
$ 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>
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}
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
$ 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.
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}
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
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) ]]
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.
$ man gpg
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.
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.
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).
Thanks to my fellow colleagues for their reading and corrections of this primer:
[ADDED 2021.04.16]
Bah! Why do I complain? This ain’t so complicated, afterall…