Security GnuPG key safety............
Your GnuPG key is your precious. John Lane explains how to create a good one and how to keep it safe from online thieves.
Your GnuPG key is your precious. John Lane explains how to make it good and keep it secret and safe.
GnuPG, the “Gnu Privacy Guard”, is a privacy tool you can use to encrypt email or verify the authenticity of software packages before installing them. It’s an implementation of the OpenPGP standard that relies on public-key cryptography keys that have provable authenticity through certification and trust.
The GnuPG documentation explains early-on that good key management is essential. So, in this tutorial, we will focus on key management and explore best-practice with that aim in mind. We’re using GnuPG version 2.1, nicknamed “Modern”.
A GnuPG key has public and private components referred to individually as a public key and private key, and together as a key-pair. Private keys are used for signing and decryption, and public keys are used for signature verification and encryption.
Public keys are contained in “certificates” along with identifying information (a user id which may be a name, email address or, perhaps, a photograph) plus one or more dependent “subkeys” that enable separate keys for signing and encryption. The rationale behind subkeys lies in GnuPG’s development history and current security-related concerns.
An individual using GnuPG collects other people’s public keys, possibly obtaining a certificate from a key server, along with their own key-pairs in their GnuPG keyring. Depending on context, ‘key’ can mean key-pair, private key, public key, subkey or certificate.
We’ll explore these concepts as a hypothetical new user who can’t wait to start encrypting everything. Let’s create that user now; something like this: $ sudo useradd -m alice $ sudo -i -u alice
Set your preferences
The first thing to do is configure GnuPG. It uses a directory (~/. gnupg by default) to store its configuration, runtime information and the keyring. It can create this directory automatically, but manually creating it enables us to specify some preferences before using GnuPG for the first time. Do so, using restricted access permissions to secure it: $ mkdir -m 700 ~/.gnupg
Although optional (GnuPG assumes a default configuration), writing a configuration file allows us to set some parameters to customise personal preference: # ~/.gnupg/gpg.conf keyserver hkps://hkps.pool.sks-keyservers.net personal-cipher-preferences AES256 AES192 AES CAST5 personal-digest-preferences SHA512 SHA384 SHA256 SHA224 cert-digest-algo SHA512 default-preference-list SHA512 SHA384 SHA256 SHA22
AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed
This configuration example sets the default key server from where public key certificates can be obtained and states preferred cipher and digest (hashing) algorithms. The defaultpreference-list defines those preferences that will be included when generating new keys so that third parties using them know what we would prefer them to use. Together, these preferences control the available algorithms that GnuPG may use and, as an example, we express our preference for more secure ones. The default algorithms, however, are suitable for most use-cases should you prefer to stick with them.
The easiest way to create a key is to enter gpg --gen-key and follow the prompts that request name, email address and a passphrase. This method uses default settings (including those from the configuration file) and would produce a nonexpiring 2048-bit “primary”, or “master”, RSA key for signing and certification, a user id formed from the given name and email, and a subkey (also 2048-bit RSA) for encryption.
Another approach is to use GnuPG’s batch mode because it allows the required information to be provided in a parameter file instead of prompting for it to be entered interactively. The parameter file allows more detailed configuration than the interactive tool and also serves as a record of the parameters used to generate the key.
$ cat <<EOF > alice.keyparams Key-Type: RSA Key-Length: 4096 Key-Usage: sign Subkey-Type: RSA Subkey-Length: 4096 Subkey-Usage: encrypt Name-Real: Alice Name-Email: email@example.com Passphrase: alice1234 Expire-Date: 1y EOF $ gpg --verbose --gen-key --batch alice.keyparams
The key generation may take a little while because it requires “entropy” to provide sufficient random data; the verbose option asks gpg for progress feedback.
Our example generates larger 4096-bit keys (just to illustrate the capability, 2048-bit keys are secure for most purposes) that will expire one year after creation. An expired key is invalid and cannot be used to sign or encrypt, and setting a date when this should occur is a precautionary measure that doesn’t hurt but would be beneficial in the event that the private key or its passphrase were ever lost. In such cases where a key cannot be revoked it is of some comfort to know that it will expire at some point. Should the worst not happen, the expiry date can be changed, even if the key has already expired. Note that expired keys can still decrypt already encrypted messages. The example parameter file includes the passphrase but
gpg will prompt for it interactively if it is omitted from the file. Other options may be given, such as “preferences” which would override the default preference list in gpg.conf.
The user id consists of the given name (“Name-Real”), email (“Name-Email”) and an optional comment (“NameComment”) that we didn’t use. Popular opinion in the PGP community recommends against using comments because they are not part of your identity. Bear in mind that you can’t change a user id but you can revoke them and add new ones. And the key is... Once key generation completes, gpg can display a summary of what was produced with its --list-keys (or -k) command: $ gpg -k alice pub rsa4096 2016-10-03 [SC] [expires: 2017-10-03]
109FB60CAD48C7820CF441A661EB6F7F34CE2E54 uid [ultimate] Alice <firstname.lastname@example.org> sub rsa4096 2016-10-03 [E] [expires: 2017-10-03]
This shows three things: a 4096-bit primary key, the user id and a subkey. The [ultimate] annotation on the user id reflects trust in yourself (it’s your key) and means your key is valid and you will trust any other keys you sign with it.
The long string of hexadecimal characters is the primary key’s “fingerprint”, a 160-bit SHA1 hash of the key material. The pub prefix to the primary key tells you that you’re looking at the public key; the sub prefix conveys similar meaning for the subkey. The two corresponding private keys aren’t listed, but also exist in the newly created key ring (that is stored within the ~/.gnupg directory). Use gpg --list-secret-keys (or its short-form -K) to list them (see over):
$ gpg -K sec rsa4096 2016-10-03 [SC] [expires: 2017-10-03]
109FB60CAD48C7820CF441A661EB6F7F34CE2E54 uid [ultimate] Alice <email@example.com> ssb rsa4096 2016-10-03 [E] [expires: 2017-10-03]
Here, in otherwise similar output, the prefixes are sec (secret) for the primary private key and ssb for the subkey.
The key’s fingerprint is the primary way to identify it but they are usually referred to using a shorter key id of the last eight characters of the fingerprint. These short key ids are prone to collision, so a longer key id of 64 bits (the last 16 characters) can be used instead. They’re still collision-prone, but to a lesser extent; if in doubt, use the fingerprint!
Add --keyid-format short to gpg commands to request they output the short key format, or --keyid-format long for the longer one. If you use --fingerprint the fingerprint will be displayed in a more readable form. Like this: short “34CE2E54” long “61EB6F7F34CE2E54” fingerprint “109F B60C AD48 C782 0CF4 41A6 61EB 6F7F 34CE 2E54” The fingerprint of the subkey is not displayed unless --fingerprint is given twice. Our new key is “self-certified” which means the primary key signs the user id and subkey parts to assert that it owns them. You can view these signatures: $ gpg --list-sigs alice pub rsa4096 2016-10-03 [SC] [expires: 2017-10-03] uid [ultimate] Alice <firstname.lastname@example.org> sig 3 61EB6F7F34CE2E54 2016-10-03 Alice <alice@ example.org> sub rsa4096 2016-10-03 [E] [expires: 2017-10-03] sig 61EB6F7F34CE2E54 2016-10-03 Alice <alice@example. org>
Signatures are listed beneath the thing they are associated with. The display shows two signatures: one for the user id and the other for the subkey.
The two “sig” lines shown above display the signing key id, date and user id. The space after the “sig” may contain flags such as the “3” displayed on the primary key’s signature which indicates the effort made when verifying a key. GnuPG assigns 3, the highest level, to the signatures it makes during the key generation.
In addition to the self-certification signatures added by GnuPG, third parties may also sign the uid entries on your key to assert their confidence that the key and user id belong together and to you. Such signatures strengthen your key and help you build your web of trust.
So that’s the basic key set up and signed and ready for use. You can use it as it is, but think about what it would mean if it was lost: a key in the wrong hands can be used to masquerade as you, signing documents in your name and reading documents encrypted for your eyes only.
You increase the risk of this happening by installing your key on many devices, especially devices such as laptops, phones or tablets which are frequently taken to public places where they are easily stolen, left behind or otherwise lost.
It would be better to not install your key on such devices in the first place. However, that isn’t practical if you need to sign and encrypt on them. You can, however, use subkeys to help reduce and contain that risk because they have the fortunate property that they can be separated from the primary key, allowing it to be secured offline, and they can expire or be revoked independently.
You can create an additional signing-only subkey so that you have two: one for signing and another for encryption. You then detach those subkeys from the master key and only install the subkeys on your everyday devices. Thus: $ gpg --edit-key alice gpg> addkey
The interactive interface requires selection of key type, usage (ie, signing, encryption), length (bits) and duration (validity period) which may be non-expiring or specified in days, weeks, months or years.
If you wish, you can give the subkeys a passphrase that is different from the primary key. You can either do this while in edit mode or you can do it directly: $ gpg --passwd alice
Regardless of the method chosen, GnuPG iterates through all keys but you can decline those you don’t want to alter; there is no way to specify a single key.
Once you have your subkeys, you should export them without the primary key: $ gpg --export-secret-subkeys alice > subkeys.gpg
GnuPG will prompt for the passphrase before exporting the subkeys. You can then use a temporary keyring to review what was exported: $ mkdir -m 700 .gnupg-temp $ gpg --homedir .gnupg-temp --import subkeys.gpg $ gpg --homedir .gnupg-temp -K sec# rsa4096 2016-10-04 [SC] [expires: 2017-10-04] ssb rsa4096 2016-10-04 [E] [expires: 2017-10-04] ssb rsa2048 2016-10-04 [S] [expires: 2017-04-02]
The --homedir tells GnuPG to use a specific directory (which can have any name but must pre-exist) instead of ~/.gnupg. The hash mark following the sec tag indicates that the secret key is absent from this keyring; only the secret subkeys are present. The annotations show that the subkeys can encrypt (“E”) and sign (“S”) data and that the primary key can both sign data and certify (“C”) other keys.