OpenPGP Key Management HowTo
Contents
- Introduction
- Prerequisites
- Configuration
- Structure of an OpenPGP key
- Setup the offline environment
- Create a new offline/working key
- Install the working key
- Certify a key with the offline key
- Modify the offline/working key
- Revoke the offline/working key
- Details of the exported files
- References
- History
1. Introduction
1.1. About
This document describes the steps of managing OpenPGP keys which are in particular the topics generation, certification, modification, and revocation. Other topics related to mere usage, like encrypting and signing data, are also treated briefly where applicable but do not have high priority.
1.2. Scenario
The underlying scenario of this document is having two separate keys, a working key for daily usage and an offline key for special use cases:
The working key is used and stored at one or several workplace computers. This computer can be a portable one, e. g., a notebook or a smartphone. More generally, it is used in an environment which is not considered fully trustworthy or which is not or cannot be heavily secured and hardened.
The offline key, which is called master key sometimes, in contrast, must strictly be kept secure and apart from the working key. There is a wide range of interpretations from storing the key as digital file in some different directory even on the same computer to printing it on a sheet of paper which is put in a safe-deposit box.
The actual interpretations of "trustworthy", "secure", etc. have to be specified by each individual user. The principle of prudence should establish the baseline.
1.3. Audience
You should already be familiar at least with the basic concepts of public-key cryptography and should also know the differences between asymmetric and symmetric cryptosystems.
You should run a GNU/Linux system. If you are running a different operating system you may consider most parts of this document helpful, too.
Applications with graphical user interfaces are not used in this document because they hide too much information on the exact working methods and the context of the intended actions. Further on, the degree of delegating trust and control from the user over to some software is retained as low as possible. A good look-and-feel is reasonably considered as a major con in this context. Therefore, you also should feel comfortable with working on the command line.
Finally and also to clarify things in the first place: This document will not be suitable for those computer users who instinctively click on all buttons presented to them, in order to quickly proceed under all circumstances with some actions that they do not (want to) understand and the possibly harmful consequences of which for others or for themselves they are not interested in.
Please note
OpenPGP key management is a complex subject. You should not be discouraged. But you should not expect to get through it in just a few minutes either.
1.4. Status and Versions
This document fully covers the scenario described above and provides enough references to allow a deeper research of the technical backgrounds. However, its style and its structure are considered as a work in progress. Also, some possibly useful but rather secondary aspects might be added later.
The latest version of this document is available at https://wiki.lug-in.de/OpenPGP/KeyManagementHowTo.
This document is also available in plain text, HTML or PDF format.
For a short history of this document see the section History below.
1.5. Legal information
The OpenPGP Key Management HowTo by Mathias Bauer is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
1.6. Acknowledgement
This document would not have been possible without the help and the input of many people. I want to say thank you to
Werner Koch and the developer team for the GNU Privacy Guard (GnuPG) software,
the subscribers of the mailinglists gnupg-devel and gnupg-users for their valuable background information and for many hints,
Kazu Yamamoto, for the PGPdump software,
Henk P. Penning, for the PGP pathfinder and key statistics tool, and last but not least
all members of the Linux and Unix User Group Ingolstadt for the constant inspiration and for providing an experimental ground.
2. Prerequisites
For operating on OpenPGP keys, an installation of the GNU Privacy Guard (GnuPG) is required, which is recent to some extent.
1 $ gpg --verbose --version
2 gpg (GnuPG) 1.4.12
3 Copyright (C) 2012 Free Software Foundation, Inc.
4 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
5 This is free software: you are free to change and redistribute it.
6 There is NO WARRANTY, to the extent permitted by law.
7
8 Home: ~/.gnupg
9 Supported algorithms:
10 Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA
11 Cipher: 3DES (S2), CAST5 (S3), BLOWFISH (S4), AES (S7), AES192 (S8),
12 AES256 (S9), TWOFISH (S10), CAMELLIA128 (S11), CAMELLIA192 (S12),
13 CAMELLIA256 (S13)
14 Hash: MD5 (H1), SHA1 (H2), RIPEMD160 (H3), SHA256 (H8), SHA384 (H9),
15 SHA512 (H10), SHA224 (H11)
16 Compression: Uncompressed (Z0), ZIP (Z1), ZLIB (Z2), BZIP2 (Z3)
Other versions of GnuPG, especially patched ones like the one from the Debian GNU/Linux 'wheezy' (stable) release shown above or newer ones, may work as well.
Using a GNU/Linux live system like Debian GNU/Linux Live is strongly recommended because it will completely "live" in the computer's memory during runtime and therefore it does not leave any digital traces on the hard disk(s).
For further details, see the reference section Software below.
Also there should be several storage devices ready, e. g., USB sticks or SD cards. Of course, these devices should not be used for any other purpose.
3. Configuration
Two different configurations have to be developed, as already indicated in the section Scenario above:
The configuration of the working environment, the working configuration, must bear in mind that GnuPG has to collaborate with other applications like mail user agents, etc. Therefore, some settings must be lax or should not be specified at all.
The configuration of the offline environment, the offline configuration, in contrast, can be held rather restrictive because there's no need for GnuPG to consider any other applications.
A good rule of thumb for changing configurations is to keep the defaults. However, depending on the above scenario and on general considerations, changing some of GnuPG's settings is really recommended.
The following subsections try to group the settings usefully and discuss the details and the differences between the offline and the working configuration:
Where applicable, a short justification is given for a change. For further details, see the GnuPG manual page and the section References below.
Two example configuration files are provided: gpg-working.conf and gpg-offline.conf. Each of them must be renamed to gpg.conf in the respective environment's GnuPG home directory.
3.1. Keys
default-key KEY_ID (optional)
- This will specify the default key to sign or certify with if several secret keys are used (which are not this document's scenario). Otherwise the default key is the first key found in the secret key ring. Neither the working configuration nor the offline configuration need this option to be set because the default key can be specified by the respective application or on the GnuPG command line.
trusted-key KEY_ID (recommended)
- This option defines a key which is considered fully trustworthy. Note that the specified key need not be available in the key rings. All 16 characters of the long key ID must be specified here.
3.2. Key rings
One or several options keyring FILE can be used to make additional and maybe read-only key rings known to GnuPG (optional).
If the specified FILE begins with a tilde and a slash, these will be replaced by the HOME directory. If the filename does not contain a slash, it will assumed to be in the GnuPG home directory (~/.gnupg if --homedir or GNUPGHOME is not used).
3.3. Key servers
The offline environment is designed as a closed system. It must not use any key servers.
no-auto-key-locate (recommended)
- Keys must neither be located nor retrieved automatically.
Any other lines with options keyserver ... should be commented out in the offline configuration.
The option no-auto-key-locate also is recommended for the working configuration. Although it is a reasonable assumption to consider neither the key servers and the data they provide nor their operators as trustworthy, key servers can surely be used in the working environment - but not automatically!
keyserver-options STRING (recommended)
Use the following arguments for the option keyserver-options. Multiple arguments are delimited by spaces or commas. As there are different types of key servers, there are different default arguments.
no-auto-key-retrieve (recommended)
- When verifying signatures, keys must not be retrieved automatically.
ca-cert-file (optional)
- Override the default X.509 certificate store, which may be a directory or a file depending on the library used, to be used to secure the communication with a key server (TLS).
check-cert (recommended)
- If the key server (only HKPS and LDAPS) presents X.509 certificates (TLS), they will be checked.
no-honor-keyserver-url (recommended)
- When refreshing a key, any preferred key server URL is ignored as most key servers are synchronized anyway.
no-honor-pka-record (recommended)
- PKA record information is not used.
include-disabled (recommended)
- Include keys which are marked as disabled on the key server (not HKP) when searching for them.
include-revoked (recommended)
- Include keys which are marked as revoked on the key server when searching for them. Not all key servers differentiate between revoked and unrevoked keys.
include-subkeys (recommended)
- When receiving keys, include subkeys as potential targets (not for HKP).
To have even more control over the communication with key servers and to receive additional output from the helper programs, the options use-temp-files, keep-temp-files, debug, and verbose can be used. The latter may also be specified several times.
The following block lists the modifications discussed in this subsection. Note that the configuration file must not contain any line breaks.
no-auto-key-locate keyserver-options no-auto-key-retrieve check-cert no-honor-keyserver-url \ no-honor-pka-record include-disabled include-revoked include-subkeys \ debug verbose verbose verbose
As most of the key servers synchronize their data, it's a good idea to use a (regional) key server pool that directs each connection via round robin DNS to a certain server. In addition to the above configuration block, use
keyserver hkp://pool.sks-keyservers.net
The more secure HKPS protocol, which is HKP secured by TLS/SSL, should really be considered using instead. Download the X.509 certificate sks-keyservers.netCA.pem, verify it and replace the above setting by:
keyserver hkps://hkps.pool.sks-keyservers.net \ ca-cert-file=/absolute/path/to/CA/sks-keyservers.netCA.pem
For further details, see the reference section Key servers below. There is an overview of the SKS key server pools of Kristian Fiskerstrand together with some statistical data. And there is also a detailed description about the OpenPGP HTTP Keyserver Protocol (HKP) by David Shaw.
3.4. Signatures and trust
no-ask-cert-level (recommended)
default-cert-level 0 (recommended)
min-cert-level 2 (recommended)
- When certifying OpenPGP keys, the major point keys is: Is this the right key and does it really belong to a given user? This is not a question of "perhaps" or of "trust" but a question of control.
In contrast to a sophisticated certification policy, a "certification level" does not make sense and can even be rather dangerous. Actually, parts of the OpenPGP standard RFC 4880, sec. 5.2.1 (types 0x10-0x13), barely comply with basic requirements of any policy.
The three settings above reflect this thoughts and are the defaults, anyway. For further details, see the discussion in the section Certify a key with the offline key below and also Daniel Kahn Gillmor's article, gpg --ask-cert-level considered harmful in the reference section Articles below.
ask-cert-expire (recommended)
default-cert-expire 0 (recommended)
- When certifying OpenPGP keys, an expiration time may be asked for. The default is, that key certification signatures do not expire.
auto-check-trustdb (recommended)
- Information on the web of trust is automatically kept up to date when modifying keys or key rings.
completes-needed 1 (recommended)
marginals-needed 3 (recommended)
max-cert-depth 5 (recommended)
- Adjustments for the web of trust calculations:
- Specify the number of completely (default: 1) or marginally (default: 3) trusted users to introduce a new key signer.
- Specify the maximum depth of a certification chain (default: 5).
require-cross-certification (recommended)
trust-model pgp (recommended)
- The PGP trust model is always followed.
force-v4-certs (recommended)
no-force-v3-sigs (recommended)
The OpenPGP standard RFC 4880 is followed strictly. Some outdated and mostly obsolete software is not taken into account. Just as commercial products with some "special features" are not either.
ask-sig-expire (recommended)
default-sig-expire 0 (recommended)
- When signing data, an expiration time may be asked for. The default is, that signatures do not expire.
sig-notation issuer-fpr@notations.openpgp.fifthhorseman.net=%g (recommended)
When creating a data signature, the long ID (64 bit) of the issuers's key is included. It makes sense to also include its full fingerprint (160 bit) in the signature. Although this notation is not standardized in the current OpenPGP standard RFC 4880, it is very likely to be used in the next version.
Note that this notation does not apply for certification signatures. For these signatures the cert-notation option is used. However, using it in order to face the issue described above, is currently not recommended.
The following block lists the modifications discussed in this subsection.
no-ask-cert-level default-cert-level 0 min-cert-level 2 ask-cert-expire default-cert-expire 0 auto-check-trustdb completes-needed 1 marginals-needed 3 max-cert-depth 5 require-cross-certification trust-model pgp force-v4-certs no-force-v3-sigs ask-sig-expire default-sig-expire 0 sig-notation issuer-fpr@notations.openpgp.fifthhorseman.net=%g
3.5. Algorithms
The following tables present an overview of the algorithms defined by the OpenPGP standards RFCs 4880 (2007) and its extensions RFC 5581 (2009) and RFC 6637 (2012). The column "GnuPG" lists the text name used by GnuPG, e.g., for the configuration. The column "Level" shows whether the respective algorithm may, should or must be implemented in a standard-compliant software.
Public-key algorithms |
|||
ID |
Description and definition |
GnuPG |
Level |
1 |
RSA (Encrypt or Sign) [ HAC ] |
RSA |
SHOULD |
2 |
RSA Encrypt-Only [ HAC ] |
RSA-E |
deprecated |
3 |
RSA Sign-Only [ HAC ] |
RSA-S |
deprecated |
16 |
ELG-E |
MUST |
|
17 |
DSA |
MUST |
|
18 |
ECDH public key algorithm [ RFC6637 ] |
|
MUST |
19 |
|
MUST |
|
20 |
Reserved (formerly Elgamal Encrypt or Sign) |
|
|
21 |
Reserved for Diffie-Hellman (X9.42, as defined for IETF-S/MIME) |
|
|
Symmetric-key algorithms |
|||
ID |
Description and definition |
GnuPG |
Level |
0 |
Plaintext or unencrypted data |
|
MAY |
1 |
IDEA [ IDEA ] |
|
MAY |
2 |
TripleDES (DES-EDE, 168 bit key derived from 192) [ SCHNEIER, HAC ] |
3DES |
MUST |
3 |
CAST5 (128 bit key) [ RFC2144 ] |
CAST5 |
SHOULD |
4 |
Blowfish (128 bit key, 16 rounds) [ BLOWFISH ] |
BLOWFISH |
MAY |
5 |
Reserved |
|
|
6 |
Reserved |
|
|
7 |
AES with 128 bit key [ AES ] |
AES |
SHOULD |
8 |
AES with 192 bit key [ AES ] |
AES192 |
MAY |
9 |
AES with 256 bit key [ AES ] |
AES256 |
MAY |
10 |
Twofish with 256 bit key [ TWOFISH ] |
TWOFISH |
MAY |
11 |
Camellia 128 bit key [ RFC3713 ] |
CAMELLIA128 |
MAY |
12 |
Camellia 192 bit key [ RFC3713 ] |
CAMELLIA192 |
MAY |
13 |
Camellia 256 bit key [ RFC3713 ] |
CAMELLIA256 |
MAY |
Hash algorithms |
|||
ID |
Description and definition |
GnuPG |
Level |
1 |
MD5 [ HAC ] |
MD5 |
deprecated |
2 |
SHA-1 [ FIPS180 ] |
SHA1 |
MUST |
3 |
RIPE-MD/160 [ HAC ] |
RIPEMD160 |
MAY |
4 |
Reserved |
|
|
5 |
Reserved |
|
|
6 |
Reserved |
|
|
7 |
Reserved |
|
|
8 |
SHA256 [ FIPS180 ] |
SHA256 |
MAY |
9 |
SHA384 [ FIPS180 ] |
SHA384 |
MAY |
10 |
SHA512 [ FIPS180 ] |
SHA512 |
MAY |
11 |
SHA224 [ FIPS180 ] |
SHA224 |
MAY |
Data compression algorithms |
|||
ID |
Description and definition |
GnuPG |
Level |
0 |
Uncompressed |
Uncompressed |
MUST |
1 |
ZIP [ RFC1951 ] |
ZIP |
SHOULD |
2 |
ZLIB [ RFC1950 ] |
ZLIB |
MAY |
3 |
BZip2 [ BZ2 ] |
BZIP2 |
MAY |
Use the listing presented in the section Prerequisites above to examine the current GnuPG's capabilities. Note that the elliptic curve algorithms have not yet been implemented in the GnuPG version which is used for this document. (This is only a minor drawback as these algorithms are not widely used yet.)
For further details, see the reference sections Algorithms and Recommendations below.
Note that there are many purposes for the selection of the algorithms below. First, only secure algorithms are selected, of course. Deprecated or even broken ones are certainly not specified. Also, the basic tenor for recommendations in this document is to avoid a cryptographic monoculture. However, this is a rather political question.
cert-digest-algo SHA512 (recommended)
The message digest algorithm used when certifying a key should belong to the SHA-2 algorithm family. For further details, see Daniel Kahn Gillmor's HOWTO for Migration off of SHA-1 in OpenPGP in the reference section Articles below.
enable-dsa2 (recommended)
personal-*-preferences STRING (recommended)
Every OpenPGP key, or more exact, every key's user ID has preferences for cipher algorithms, digest algorithms, and data compression algorithms. If these preferences can not be found in some key, the defaults of the OpenPGP standard RFC 4880, sec. 13, will be used. These defaults are TripleDES, SHA-1, and ZIP/Uncompressed.
Setting personal-cipher-preferences, personal-digest-preferences, and personal-compress-preferences allows safely overriding the recipients' algorithm choices. Finally, GnuPG uses those algorithms which are included in all recipients' preferences and which are listed first in the personal-*-preferences settings.
personal-cipher-preferences STRING
- The default preference string is: AES256 AES192 AES CAST5 3DES. The recommended string is: AES256 CAMELLIA256 TWOFISH AES192 CAMELLIA192 AES CAMELLIA128 CAST5 3DES.
personal-digest-preferences STRING
- The default preference string is: SHA256 SHA1 SHA384 SHA512 SHA224. The recommended string is: SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1.
personal-compress-preferences STRING
- The default preference string is: ZLIB BZIP2 ZIP Uncompressed. As the compression rations are generally better for BZIP2 than for ZLIB, the recommended string is: BZIP2 ZLIB ZIP Uncompressed.
default-preference-list STRING (recommended)
These preferences are used when creating new keys and become the default for the setpref command when modifying the offline key. Use the same preferences as in the three personal-*-preferences settings and put them in one line. For an example, see the section Change a user ID's preferences below.
The following block lists the modifications discussed in this subsection. Note that the configuration file must not contain any line breaks.
cert-digest-algo SHA512 enable-dsa2 personal-cipher-preferences AES256 CAMELLIA256 TWOFISH AES192 CAMELLIA192 \ AES CAMELLIA128 CAST5 3DES personal-digest-preferences SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 personal-compress-preferences BZIP2 ZLIB ZIP Uncompressed default-preference-list AES256 CAMELLIA256 TWOFISH AES192 CAMELLIA192 AES \ CAMELLIA128 CAST5 3DES SHA512 SHA384 SHA256 SHA224 RIPEMD160 SHA1 \ BZIP2 ZLIB ZIP Uncompressed
3.6. Security and privacy
Operating with OpenPGP key material should not emit more information as is absolutely necessary, i. e., no (unnecessary) user IDs, no comments, no version strings, etc.
For a comparison and for details of the algorithms specified in this subsection, see the previous subsection as well as the reference sections Algorithms and Recommendations below.
no-allow-freeform-uid (recommended)
- When generating new user IDs, their format is checked. Basically, the well known email address format is enforced.
no-allow-non-selfsigned-uid (recommended)
- Importing and usage of user IDs which are not self-signed is not allowed.
no-comments (recommended)
- No comment is included in ASCII armored output.
no-default-recipient (recommended)
Normally there's no default recipient. Special issues, like a copy-to-self setting in some mail user agent, should not be handled by GnuPG globally but by the respective applications.
no-emit-version (recommended)
- No version string is included in ASCII armored output.
exit-on-status-write-error (recommended)
force-mdc (recommended)
- Use encryption with a modification detection code.
no-greeting (recommended)
- No copyright message is shown.
require-secmem (recommended)
- GnuPG will refuse to run if it cannot get secure memory.
s2k-cipher-algo AES256 (recommended)
- The default S2K cipher algorithm CAST5 (128 bit) is replaced. This, for example, enhances the security of passphrases and secret keys.
s2k-digest-algo SHA512 (recommended)
- The default S2K hash algorithm SHA-1 (160 bit) is replaced.
verify-options STRING (optional/recommended)
Use the following arguments for the option verify-options. Multiple options are delimited by spaces or commas.
Note that specifying verify-options is optional for the working configuration, because there are some unwanted interferences with applications or scripts that use pure gpg commands and parse their output. This is not recommended, of course. So, it might be better to stay with the built-in defaults. However, specifying verify-options for the offline configuration is not critical.
no-pka-lookups
no-pka-trust-increase
- PKA record information is not used.
show-keyserver-urls
- Show any preferred key server URL in the signature being verified.
show-notations
- Show any notations in signatures being verified.
no-show-photos
- Do not display any photo IDs.
show-policy-urls
- Show policy URLs in the signature being verified.
no-show-primary-uid-only
- Show all user IDs during signature verification.
show-uid-validity
- Show the calculated validity of the user IDs.
show-unusable-uids
- Show revoked and expired user IDs during signature verification.
The following block lists the modifications discussed in this subsection. Note that the configuration file must not contain any line breaks.
no-allow-freeform-uid no-allow-non-selfsigned-uid no-comments no-default-recipient no-emit-version exit-on-status-write-error force-mdc no-greeting require-secmem s2k-cipher-algo AES256 s2k-digest-algo SHA512 verify-options no-pka-lookups no-pka-trust-increase show-keyserver-urls \ show-notations no-show-photos show-policy-urls \ no-show-primary-uid-only show-uid-validity show-unusable-uids
3.7. Miscellaneous
compress-level 9 (recommended)
- Use the maximum compression level for the ZIP and ZLIB algorithms.
bzip2-compress-level 9 (recommended)
- Use the maximum compression level for the BZIP2 algorithm.
display-charset utf-8 (recommended)
utf8-strings (recommended)
- Use the native UTF-8 encoding. Note that GnuPG does not recode user-supplied data.
keyid-format long (recommended)
Long key IDs should be used to reduce ambiguity. Note that key IDs (the short 32 bit ones and the long 64 bit ones) consist of the rightmost part of the key's fingerprint (160 bit). They are not unique! In fact, there exist many keys which do have the same key ID! For further details, see Daniel Kahn Gillmor's article OpenPGP Key IDs are not useful in the reference section Articles below.
list-options STRING (optional/recommended)
Use the following arguments for the option list-options. Multiple options are delimited by spaces or commas.
Note that specifying list-options is optional for the working configuration, because there are some unwanted interferences with applications or scripts that use pure gpg commands and parse their output. This is not recommended, of course. So, it might be better to stay with the built-in defaults. However, specifying list-options for the offline configuration is not critical.
show-keyring
- Show the key ring name at the head of key listings.
show-keyserver-urls
- Show any preferred key server URLs found in signatures.
show-notations
- Show all signature notations.
no-show-photos
- Do not display any photo IDs.
show-policy-urls
- Show policy URLs found in signatures.
show-sig-expire
- Show signature expiration dates.
show-uid-validity
- Show the calculated validity of the user IDs.
show-unusable-subkeys
- Show revoked and expired subkeys.
show-unusable-uids
- Show revoked and expired user IDs.
photo-viewer /bin/true (optional/recommended)
Use a dummy photo viewer. This is not needed for the offline configuration and may not be needed for the working configuration either.
The following block lists the modifications discussed in this subsection. Note that the configuration file must not contain any line breaks.
compress-level 9 bzip2-compress-level 9 display-charset utf-8 utf8-strings keyid-format long list-options show-keyring show-keyserver-urls show-notations \ no-show-photos show-policy-urls show-sig-expire show-uid-validity \ show-unusable-subkeys show-unusable-uids photo-viewer /bin/true
4. Structure of an OpenPGP key
Speaking about "the OpenPGP key" actually is lax and misleading at least. When looking at the details, it is very irritating, too. In fact there are several keys and even more several non-key components forming altogether an OpenPGP key. This section explains the basics of its structure.
There is always a public part and a secret part of an OpenPGP key. Both parts form a sequence of packets.
There is always a main key and zero or more subkeys, each of which have a public key part and a secret key part.
For example, in the figure above, the secret part consists of the packets (1) to (3) and the public part consists of the packets (4) to (6). Also, there is a main key which consists of the packets (1) and (4). And there are two subkeys: the first one consists of the packets (2) and (5), the second one of the packets (3) and (6).
Subkeys, in general, will be needed if the cryptographic functionality is split into several keys, which is usually regarded as a good thing. This includes
the certification of other keys,
signing and verifying data,
encrypting and decrypting data, and
authentication.
For further details on subkeys, see the Debian wiki article Using OpenPGP subkeys in Debian development in the reference section Articles below.
Keep the scheme above in mind when generating the offline key and the working key. This is covered by the section Create a new offline/working key below. It is very important to realize, that the offline key will consist of the packets (1) to (6), but the working key will have the packet (1) stripped off!
So far, only components of an OpenPGP key with real "key material" have been described. This means, loosely speaking, those (very large) numbers, that the cryptographic algorithms and the underlying mathematics are based upon. However, there are other components beyond that, too. The figure below shows the public part of an OpenPGP key:
There are one or more user ID packets. Each user ID packet has zero or more signature packets (certifications).
For each subkey packet, there is also a signature package.
As the figure above shows, signature packets form the glue between the main key and the user IDs on the one hand. On the other hand, they also bind together the main key and the subkeys. There are several different types of signature packets. The following ones are commonly seen on OpenPGP keys:
Certification signatures of a User ID and Public-Key packet certify (the verification of) the claim, that the owner of the key is the user ID specified. Signatures from the key's owner are called self-signatures.
Subkey Binding Signatures are a statement by the top-level signing keys that indicates that they own a subkey.
Key revocation signatures
Subkey revocation signature
Certification revocation signatures revoke earlier user ID certification signature.
The secret part of an OpenPGP key looks quite similar.
For further details, see the very well written OpenPGP standard RFC 4880 in the References section below.
5. Setup the offline environment
As already mentioned in the section Scenario above, setting up the offline environment depends on the subjective interpretation of "trustworthy", "secure", etc. Therefore, the following list serves as an example.
First, disconnect the computer from any network.
- Boot a GNU/Linux live system, like Debian GNU/Linux Live.
Mount some storage device and make it accessible at /mnt.
- Finally, open a terminal.
The actual steps related to the above actions remain beyond the scope of this document.
Make a typescript of everything printed on the terminal during the session. Use the script program to create the log file session-offline-YYYY-MM-DD.log. Finally, exit the forked shell to finish logging.
$ script -f /path/to/session-offline-YYYY-MM-DD.log
Adjust the localization settings to unify the output language. Translations of GnuPG, although being quite complete, may use some formulation which may give a wrong understanding and then may lead to wrong decisions related to security.
$ export LC_ALL=C.UTF-8
All operations will take place in a separate directory which is located on a temporary filesystem (tmpfs). Hence, this directory will totally reside in memory and digital traces on any hard disk(s) will be avoided. The directory /tmp commonly uses tmpfs. For further details, see /etc/fstab. Set the GNUPGHOME environment variable to ensure that GnuPG will use this directory instead.
$ umask 77 $ mkdir /tmp/work $ export GNUPGHOME=/tmp/work
Optionally kill a running GnuPG agent process. At least unset the environment variables GPG_AGENT_INFO and GPG_TTY.
$ killall -v gpg-agent $ unset GPG_AGENT_INFO GPG_TTY
Before continuing check the GnuPG configuration file gpg.conf and ensure that it's the correct one for the offline environment. The configuration file must be located in the directory specified by GNUPGHOME. For further details, see the Configuration section above.
Now, the offline environment is setup.
6. Create a new offline/working key
Setup the offline environment as described in the previous section.
The following subsections show the steps to create a new offline key and a new working key according to the underlying scenario described in the section Scenario above.
6.1. Create the main key
The main key is a 4096 bit RSA sign-only key. It should expire in five years at most. The key's validity can simply be extended near the end of this period of time.
1 $ gpg --gen-key
2 Please select what kind of key you want:
3 (1) RSA and RSA (default)
4 (2) DSA and Elgamal
5 (3) DSA (sign only)
6 (4) RSA (sign only)
7 Your selection? 4
8 RSA keys may be between 1024 and 4096 bits long.
9 What keysize do you want? (2048) 4096
10 Requested keysize is 4096 bits
11 [...]
12 Key is valid for? (0) 2020-02-01
13 Key expires at Fri 01 Feb 2020 12:00:00 AM CET
The (first) user ID should only contain a real name. Just do not specify an email address. A comment on user IDs should almost always be omitted, too. For further details, see Daniel Kahn Gillmor's article OpenPGP user ID comments considered harmful in the reference section Articles below.
14 You need a user ID to identify your key; the software constructs the user ID
15 from the Real Name, Comment and Email Address in this form:
16 "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"
17
18 Real name: John Q. Example
19 Email address:
20 Comment:
21 You selected this USER-ID:
22 "John Q. Example"
23
24 Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
Choose a short dummy passphrase because it is needed very often in the next steps of the process. But do not use an empty passphrase!
Follow the instructions.
For simplicity, create an environment variable with the key ID.
$ export KEYID=2F3894F9C5688391
6.2. Update the configuration file
The configuration file gpg.conf of the offline environment must be updated. Set the option trusted-key with the new key's ID as argument (16 characters):
trusted-key 2F3894F9C5688391
Of course, the configuration file of the working environment should also be updated. For further details, see the top of the section Configuration above.
6.3. Add two subkeys
For daily usage, two 3072 bit RSA subkeys are created: the first one for signing and the second one for encryption. Both subkeys should roughly be valid for one year and should expire at the same date. If desired, their validity can simply be extended near the end of this period of time. For further details, see the Debian Wiki article Using OpenPGP subkeys in Debian development in the reference section Articles below.
To add a subkey use addkey. To list all keys and user IDs use list. Finally save and quit.
1 $ gpg --edit-key $KEYID
2 gpg> addkey
3 [...]
4 Please select what kind of key you want:
5 (3) DSA (sign only)
6 (4) RSA (sign only)
7 (5) Elgamal (encrypt only)
8 (6) RSA (encrypt only)
9 Your selection? 4
10 RSA keys may be between 1024 and 4096 bits long.
11 What keysize do you want? (3072)
12 Requested keysize is 3072 bits
13 [...]
14 Key is valid for? (0) 2016-02-01
15 Key expires at Sun 01 Feb 2016 12:00:00 AM CET
16 [...]
17 gpg> addkey
18 [...]
19 Your selection? 6
20 RSA keys may be between 1024 and 4096 bits long.
21 What keysize do you want? (3072)
22 Requested keysize is 3072 bits
23 [...]
24 gpg> list
25 pub 4096R/2F3894F9C5688391 created: 2014-12-05 expires: 2020-01-31 usage: SC
26 trust: ultimate validity: ultimate
27 sub 3072R/8CB8E0FFDADD3834 created: 2014-12-05 expires: 2016-01-31 usage: S
28 sub 3072R/3EF8C012214CDCB3 created: 2014-12-05 expires: 2016-01-31 usage: E
29 [ultimate] (1). John Q. Example
30 gpg> save
The listing above shows the main key and the two subkeys with their usage flags:
C: The key may be used to certify other keys.
S: The key may be used to sign data.
E: The key may be used to encrypt communications or storage.
6.4. Add further user IDs
The key may be equipped with further user IDs with real names and email addresses. As above, comments should almost always be omitted.
To add a user ID use adduid. To list all keys and user IDs use list. Finally save and quit.
The listing above shows "unknown" trust values for the new user IDs because they are calculated after saving the key.
6.5. Specify the primary user ID
If there are several user IDs, one of them should be manually marked as primary user ID. Usually this should be the user ID without an email address.
To select or unselect a user ID use uid N. To make the selected user ID the primary one use primary. Finally save and quit.
1 $ gpg --edit-key $KEYID
2 gpg> uid 2
3 [ultimate] (1). John Example <jonny@example.net>
4 [ultimate] (2)* John Q. Example
5 [ultimate] (3) John Q. Example <john@example.com>
6 gpg> primary
7 [...]
8 gpg> list
9 [...]
10 [ultimate] (1) John Example <jonny@example.net>
11 [ultimate] (2)* John Q. Example
12 [ultimate] (3) John Q. Example <john@example.com>
13 gpg> save
6.6. Create a revocation certificate
To be prepared for the worst case which is the compromising or lost of the offline key, a revocation certificate must be created now.
You should almost never provide any reason for the revocation if asked. The revocation itself is a sufficient statement. Do not specify any optional description either. But perhaps it is a good idea to create even several revocation certificates for each of the provided reasons.
1 $ gpg --output revoke.asc --gen-revoke $KEYID
2 sec 4096R/2F3894F9C5688391 2014-12-05 John Q. Example
3
4 Create a revocation certificate for this key? (y/N) y
5 Please select the reason for the revocation:
6 0 = No reason specified
7 1 = Key has been compromised
8 2 = Key is superseded
9 3 = Key is no longer used
10 Q = Cancel
11 (Probably you want to select 1 here)
12 Your decision? 0
13 Enter an optional description; end it with an empty line:
14 >
15 Reason for revocation: No reason specified
16 (No description given)
17 Is this okay? (y/N) y
Move this revocation certificate to a medium which can be hidden at some safe place. For example, if you rate paper as more secure than bits and bytes, you might even print the revocation certificate because it is in ASCII format. In this case it is wise to print its checksum, too, in order to detect errors when retyping it to its digital form.
$ gpg --print-mds revoke.asc > revoke.sum $ cat revoke.asc revoke.sum > revoke.txt
The file revoke.txt contains all information needed and can be printed.
Warning
There is no passphrase needed to revoke a key.
- If the revoked key is published, the revocation cannot be undone.
- If the revoked key is not published, the revocation can be undone only if there is a backup.
Therefore, destroy all digital traces of the revocation certificate after it has been saved away.
6.7. Export the offline/working key
The dummy passphrase set above for the generation process only is now replaced. Two strong passphrases are needed:
The first passphrase protects the offline key. There is a risk of forgetting this passphrase because it is used less often than that of the working key. So, it's a good idea to write it down and keep it at some safe place.
The second passphrase protects the working key. This key is used in an environment where it may get compromised. Therefore, it is protected by its own passphrase, which should be different from the offline key's one.
Note that if you forget the working key's passphrase, you can easily reset it. For details see either this section or the section Export the offline/working key below. But if you forget the offline key's passphrase, you can still use all your keys and subkeys just as long as they are valid. After that you will have to regenerate them completely. Be prepared to avoid this show-stopper.
To set the offline key's passphrase use passwd. To remove any unusable signatures, which in this case are internal ones only, use clean. Finally save and quit.
Export the key components to files in ASCII format. Perhaps it is a good idea to add a timestamp YYYY-MM-DD to the filenames. For the sake of brevity this document does not.
$ gpg --armor --export $KEYID > public.asc $ gpg --armor --export-secret-keys $KEYID > offline-secret.asc $ gpg --armor --export-secret-subkeys $KEYID > working-secret.asc
Ensure that the above three commands are executed successfully. After that, remove the key rings.
$ rm pubring.gpg secring.gpg
Import only the files working-secret.asc and public.asc.
$ gpg --import working-secret.asc public.asc
To set the working key's passphrase use passwd. To remove any unusable signatures, which in this case are internal ones only, use clean. Finally save and quit.
Remove the file working-secret.asc and export the respective key components again with the modified passphrase to this file in ASCII format. Perhaps it is a good idea to add a timestamp YYYY-MM-DD to the filename. For the sake of brevity this document does not.
$ rm working-secret.asc $ gpg --armor --export-secret-subkeys $KEYID > working-secret.asc
Ensure that the above command was executed successfully.
The three resulting files contain different key components. For reference, see the section Structure of an OpenPGP key above.
The file in public.asc contains all public key parts (4) to (6).
The file offline-secret.asc contains all secret key parts (1) to (3).
The file working-secret.asc contains only the secret parts (2) and (3) of the subkeys.
The next step is grouping the files for the two environments. They must be stored on two different storage devices.
The offline key files offline-secret.asc and public.asc must be kept secret under all circumstances. The storage device containing these files must never be connected to any working machine.
The working key files working-secret.asc and public.asc must be kept secret, too, but are created for daily usage.
Next, save the two different configuration files, named gpg.conf, which were adapted near the beginning of the key generation process above.
Also, do not forget the revocation certificate revoke.asc. It will also have to be saved if it is not printed in the previous subsection. The revocation certificate should absolutely be kept apart from the working key files and it is not recommended either to save it together with the offline key files. A third storage device, which eventually is paper, is really recommended.
Warning
It is not possible to use only one storage device because in this case connecting it to some working machine will inevitably imply exposing the offline key files. The initial interpretation of the word "offline" in the section Scenario should be followed strictly.
Any temporary or less-than-ideal solution may break your security.
All files must really be located on the respective storage devices before unmounting them. Finally, clean up the offline environment and shut down the system.
7. Install the working key
The following steps will apply if a new GnuPG setup is established or if the working key should be integrated into some existing GnuPG setup.
Import the files working-secret.asc and public.asc.
$ gpg --import working-secret.asc public.asc
If there is an error with the previous command, it will help to create a backup of the existing key rings, to completely remove them, and to import the files and the backup files afterwards again.
$ mv -i secring.gpg secring-backup.gpg $ mv -i pubring.gpg pubring-backup.gpg $ gpg --import working-secret.asc public.asc $ gpg --import secring-backup.gpg pubring-backup.gpg
For simplicity, create an environment variable with the key ID.
$ export KEYID=2F3894F9C5688391
Initialize or update the web of trust.
$ gpg --trusted-key $KEYID --update-trustdb
To remove any unusable signatures, which in this case are internal ones only, use clean. Finally save and quit.
$ gpg --edit-key $KEYID clean save
The working key is now fully functional.
1 $ gpg --fingerprint --list-keys $KEYID
2 pub 4096R/2F3894F9C5688391 2014-12-05 [expires: 2020-01-31]
3 Key fingerprint = 9E3C 32C1 4F32 002B EC79 605A 2F38 94F9 C568 8391
4 uid [ultimate] John Q. Example
5 uid [ultimate] John Q. Example <john@example.com>
6 uid [ultimate] John Example <jonny@example.net>
7 sub 3072R/8CB8E0FFDADD3834 2014-12-05 [expires: 2016-01-31]
8 sub 3072R/3EF8C012214CDCB3 2014-12-05 [expires: 2016-01-31]
9 $ gpg --list-secret-keys $KEYID
10 sec# 4096R/2F3894F9C5688391 2014-12-05 [expires: 2020-01-31]
11 uid John Q. Example
12 uid John Q. Example <john@example.com>
13 uid John Example <jonny@example.net>
14 ssb 3072R/8CB8E0FFDADD3834 2014-12-05 [expires: 2016-01-31]
15 ssb 3072R/3EF8C012214CDCB3 2014-12-05 [expires: 2016-01-31]
The # after the letters sec means that the secret main key is not usable. In fact, it is missing completely. For details, see the section Structure of an OpenPGP key above.
8. Certify a key with the offline key
Setup the offline environment as described in the section above.
Get the offline key from its safe place and import the files offline-secret.asc and public.asc.
$ gpg --import offline-secret.asc public.asc
In this example Jane Smith's key should be certified. This document leaves out all aspects related of identity checking and policy matters. As to the key's user ID, it is assumed
- that Jane Smith's identity is proved and
that she has full control over the given email address jane@example.org.
So, import the public key to be certified.
1 $ gpg --verbose jane-smith.asc
2 pub 2048R/A74017B3538266D1 2013-06-09 Jane Smith <jsmith@example.org>
3 sig A74017B3538266D1 2013-06-09 [selfsig]
4 sub 2048R/CA15902BE41C84FD 2013-06-09 [expires: 2018-06-08]
5 sig A74017B3538266D1 2013-06-09 [keybind]
6 $ gpg --import jane-smith.asc
7 gpg: key A74017B3538266D1: public key "Jane Smith <jsmith@example.org>" imported
8 gpg: Total number processed: 1
9 gpg: imported: 1 (RSA: 1)
For simplicity, create an environment variable with Jane Smith's key ID.
$ export KEYID=A74017B3538266D1
To list all keys and user IDs use list. To check the key's certification signatures use check. Take care that a self-signature is present for each user ID. To verify its fingerprint use fpr. To select or unselect a user ID use uid N. Not selecting any user ID means working on all of them. To certify the selected one(s) use sign. To remove any unusable signatures afterwards use clean. Finally save and quit.
10 $ gpg --edit-key $KEYID
11 gpg> list
12 pub 2048R/A74017B3538266D1 created: 2013-06-09 expires: 2018-06-08 usage: SC
13 trust: unknown validity: unknown
14 sub 2048R/CA15902BE41C84FD created: 2013-06-09 expires: 2018-06-08 usage: E
15 [ unknown] (1). Jane Smith <jsmith@example.org>
16
17 gpg> check
18 uid Jane Smith <jsmith@example.org>
19 sig!3 A74017B3538266D1 2013-06-09 never [self-signature]
20
21 gpg> fpr
22 pub 2048R/A74017B3538266D1 2013-06-09 Jane Smith <jsmith@example.org>
23 Primary key fingerprint: 8417 30E4 A2A9 895C 433B 4E68 A740 17B3 5382 66D1
24
25 gpg> sign
26 pub 2048R/A74017B3538266D1 created: 2013-06-09 expires: 2018-06-08 usage: SC
27 trust: unknown validity: unknown
28 Primary key fingerprint: 8417 30E4 A2A9 895C 433B 4E68 A740 17B3 5382 66D1
29
30 Jane Smith <jsmith@example.org>
31
32 This key is due to expire on 2018-06-08.
33 Do you want your signature to expire at the same time? (Y/n) n
34 Please specify how long the signature should be valid.
35 0 = signature does not expire
36 <n> = signature expires in n days
37 <n>w = signature expires in n weeks
38 <n>m = signature expires in n months
39 <n>y = signature expires in n years
40 Signature is valid for? (0) 0
41 Signature does not expire at all
42 Is this correct? (y/N) y
43 Are you sure that you want to sign this key with your
44 key "John Q. Example" (2F3894F9C5688391)
45
46 Really sign? (y/N) y
47 [...]
48 gpg> clean
49 [...]
50 gpg> save
Export the certified key to a file in ASCII format and copy it to the storage device.
51 $ gpg --armor --export $KEYID > jane-smith-certified.asc
52 $ gpg --verbose jane-smith-certified.asc
53 pub 2048R/A74017B3538266D1 2013-06-09 Jane Smith <jsmith@example.org>
54 sig A74017B3538266D1 2013-06-09 [selfsig]
55 sig 2F3894F9C5688391 2014-12-06 John Q. Example
56 sub 2048R/CA15902BE41C84FD 2013-06-09 [expires: 2018-06-08]
57 sig A74017B3538266D1 2013-06-09 [keybind]
Ensure that the file is really located on the respective storage devices before unmounting them. Finally, clean up the offline environment and shut down the system.
Note that deleting a certification signature using delsig will not make sense provided the public key is already published (with this signature). As components can only be added to an OpenPGP key, the next refresh of the public key will bring back the deleted certification signature. It should be revoked instead using revsig.
9. Modify the offline/working key
Setup the offline environment as described in the section above.
Get the offline key from its safe place and import the files offline-secret.asc and public.asc.
$ gpg --import offline-secret.asc public.asc
For simplicity, create an environment variable with the key ID.
$ export KEYID=2F3894F9C5688391
Initialize or update the web of trust.
$ gpg --trusted-key $KEYID --update-trustdb
The offline key is now fully functional. The following subsections show some common use cases of modifying the offline key:
Finally, it is necessary to complete the modification actions with exporting the offline key and the working key again.
9.1. Add a subkey
Note that it is not necessary to add a new subkey if some existing one has expired. A new expiration date can simply be set to restore its validity. For details, see the next subsection.
Also note that the usage capabilities of encrypting (E) and signing data (S) must be provided entirely by the subkeys. In this case, the main key's capabilities do not matter because it is not part of the working key!
To list all keys and user IDs use list. To add a subkey use addkey. Finally save and quit.
9.2. Extend a subkey's validity
Specifying an expiration date on keys and subkeys will give you a much finer control if some unforeseen circumstances happen.
To list all keys and user IDs use list. To select or unselect a subkey use key N. Not selecting any subkey means working on the main key. To adjust the expiration date of the selected key(s) or the main key use expire. Finally save and quit.
1 $ gpg --edit-key $KEYID
2 gpg> key 1
3 pub 4096R/2F3894F9C5688391 created: 2014-12-05 expires: 2020-01-31 usage: SC
4 trust: ultimate validity: ultimate
5 sub* 3072R/8CB8E0FFDADD3834 created: 2014-12-05 expires: 2016-01-31 usage: S
6 sub 3072R/3EF8C012214CDCB3 created: 2014-12-05 expires: 2016-01-31 usage: E
7 [...]
8 gpg> expire
9 Changing expiration time for a subkey.
10 Please specify how long the key should be valid.
11 0 = key does not expire
12 <n> = key expires in n days
13 <n>w = key expires in n weeks
14 <n>m = key expires in n months
15 <n>y = key expires in n years
16 Key is valid for? (0) 2017-02-01
17 Key expires at Wed 01 Feb 2017 12:00:00 AM CET
18 Is this correct? (y/N) y
19 [...]
20 pub 4096R/2F3894F9C5688391 created: 2014-12-05 expires: 2020-01-31 usage: SC
21 trust: ultimate validity: ultimate
22 sub* 3072R/8CB8E0FFDADD3834 created: 2014-12-05 expires: 2017-01-31 usage: S
23 sub 3072R/3EF8C012214CDCB3 created: 2014-12-05 expires: 2016-01-31 usage: E
24 [...]
25 gpg> save
9.3. Revoke a subkey
Note that it is not necessary to revoke a subkey if it has expired. A new expiration date can simply be set to restore its validity. For details, see the previous subsection.
Also note that the usage capabilities of encrypting (E) and signing data (S) must be provided entirely by the subkeys. In this case, the main key's capabilities do not matter because it is not part of the working key!
Further on, deleting a subkey using delkey will not make sense provided the public key is already published (with this subkey). As components can only be added to an OpenPGP key, the next refresh of the public key will bring back the deleted subkey. It should be revoked instead.
To list all keys and user IDs use list. To select or unselect a subkey use key N. Not selecting any subkey means working on the main key. To revoke the selected one(s) or the main key use revkey. You should almost never provide any reason for the revocation if asked. The revocation itself is a sufficient statement. Do not specify any optional description either. Finally save and quit.
1 $ gpg --edit-key $KEYID
2 gpg> key 2
3 pub 4096R/2F3894F9C5688391 created: 2014-12-05 expires: 2020-01-31 usage: SC
4 trust: ultimate validity: ultimate
5 sub 3072R/8CB8E0FFDADD3834 created: 2014-12-05 expires: 2016-01-31 usage: S
6 sub* 3072R/3EF8C012214CDCB3 created: 2014-12-05 expires: 2016-01-31 usage: E
7 [...]
8 gpg> revkey
9 Do you really want to revoke this subkey? (y/N) y
10 Please select the reason for the revocation:
11 0 = No reason specified
12 1 = Key has been compromised
13 2 = Key is superseded
14 3 = Key is no longer used
15 Q = Cancel
16 Your decision? 0
17 Enter an optional description; end it with an empty line:
18 >
19 Reason for revocation: No reason specified
20 (No description given)
21 Is this okay? (y/N) y
22 [...]
23 pub 4096R/2F3894F9C5688391 created: 2014-12-05 expires: 2020-01-31 usage: SC
24 trust: ultimate validity: ultimate
25 sub 3072R/8CB8E0FFDADD3834 created: 2014-12-05 expires: 2016-01-31 usage: S
26 This key was revoked on 2014-12-06 by RSA key 2F3894F9C5688391 John Q. Example
27 sub 3072R/3EF8C012214CDCB3 created: 2014-12-05 revoked: 2014-12-06 usage: E
28 [...]
29 gpg> save
9.4. Add a user ID
The key may be equipped with further user IDs with real names and email addresses. A comment should almost always be omitted. For further details, see Daniel Kahn Gillmor's article OpenPGP user ID comments considered harmful in the reference section Articles below.
If there are several user IDs, one of them should be manually marked as primary user ID. Usually this should be the user ID without an email address.
To list all keys and user IDs use list. To add a user ID use adduid. To select or unselect a user ID use uid N. To make the selected user ID the primary one use primary. Finally save and quit.
1 $ gpg --edit-key $KEYID
2 gpg> adduid
3 Real name: John Q. Example
4 Email address: j.example@mail.example.org
5 Comment:
6 You selected this USER-ID:
7 "John Q. Example <j.example@mail.example.org>"
8
9 Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
10 [...]
11 gpg> uid 4
12 [...]
13 [ultimate] (1). John Q. Example
14 [ultimate] (2) John Q. Example <john@example.com>
15 [ultimate] (3) John Example <jonny@example.net>
16 [ unknown] (4)* John Q. Example <j.example@mail.example.org>
17 gpg> primary
18 [...]
19 [ultimate] (1) John Q. Example
20 [ultimate] (2) John Q. Example <john@example.com>
21 [ultimate] (3) John Example <jonny@example.net>
22 [ unknown] (4)* John Q. Example <j.example@mail.example.org>
23 gpg> save
The trust values of the new user ID(s) are determined after saving the key. Therefore, the above listing shows "unknown" values.
9.5. Revoke a user ID
Note that deleting a user ID using deluid will not make sense provided the public key is already published (with this user ID). As components can only be added to an OpenPGP key, the next refresh of the public key will bring back the deleted user ID back. It should be revoked instead.
If there are still several valid user IDs after revoking, one of them should be manually marked as primary user ID. Usually this should be the user ID without an email address.
To list all keys and user IDs use list. To select or unselect a user ID use uid N. To revoke the selected one(s) use revuid. You should almost never provide any reason for the revocation if asked. The revocation itself is a sufficient statement. Do not specify any optional description either. To make a selected user ID the primary one use primary. Finally save and quit.
1 $ gpg --edit-key $KEYID
2 gpg> uid 3
3 [...]
4 [ultimate] (1). John Q. Example
5 [ultimate] (2) John Q. Example <john@example.com>
6 [ultimate] (3)* John Example <jonny@example.net>
7 gpg> revuid
8 Really revoke this user ID? (y/N) y
9 Please select the reason for the revocation:
10 0 = No reason specified
11 4 = User ID is no longer valid
12 Q = Cancel
13 (Probably you want to select 4 here)
14 Your decision? 0
15 Enter an optional description; end it with an empty line:
16 >
17 Reason for revocation: No reason specified
18 (No description given)
19 Is this okay? (y/N) y
20 [...]
21 [ultimate] (1). John Q. Example
22 [ultimate] (2) John Q. Example <john@example.com>
23 [ revoked] (3) John Example <jonny@example.net>
24 gpg> save
9.6. Change a user ID's preferences
Each user ID stores its own set of algorithm preferences (cipher, digest, compression) in the corresponding self-signature. These preferences are handled by the commands pref, showpref, and setpref. To select or unselect a user ID use uid N. Not selecting any user ID means working on all of them.
To list the actual preferences of the selected user ID(s) use showpref. Compared to the listing of pref, which is less understandable for humans, some default preferences may additionally be included:
symmetric cipher algorithms: TripleDES (see RFC 4880, sec. 13.2)
hash algorithms: SHA-1 (see RFC 4880, sec. 13.3.2)
compression algorithms: ZIP and Uncompressed (see RFC 4880, sec. 13.3.1)
Note that instead of changing the preferences directly on the key, it is strongly recommended to change the arguments of the option default-preference-list in the configuration file. After that, the setpref command can be used at the prompt without any arguments as they are taken from the configuration file. Alternately, specifying all algorithms manually as arguments of setpref is very error-prone. For further details, see the section Algorithms above.
The following example removes the AES algorithm from the cipher preferences of all user IDs.
1 $ gpg --edit-key $KEYID
2 gpg> showpref
3 [ultimate] (1). John Q. Example
4 Cipher: AES256, CAMELLIA256, TWOFISH, AES192, CAMELLIA192, AES, \
5 CAMELLIA128, CAST5, 3DES
6 Digest: SHA512, SHA384, SHA256, SHA224, RIPEMD160, SHA1
7 Compression: BZIP2, ZLIB, ZIP, Uncompressed
8 Features: MDC, Keyserver no-modify
9 [...]
10 gpg> pref
11 [ultimate] (1). John Q. Example
12 S9 S13 S10 S8 S12 S7 S11 S3 S2 H10 H9 H8 H11 H3 H2 Z3 Z2 Z1 Z0 \
13 [mdc] [no-ks-modify]
14 [...]
15 gpg> quit
16 $ gpg --verbose --version
17 [...]
18 Cipher: 3DES (S2), CAST5 (S3), BLOWFISH (S4), AES (S7), AES192 (S8),
19 AES256 (S9), TWOFISH (S10), CAMELLIA128 (S11),
20 CAMELLIA192 (S12), CAMELLIA256 (S13)
21 Hash: MD5 (H1), SHA1 (H2), RIPEMD160 (H3), SHA256 (H8), SHA384 (H9),
22 SHA512 (H10), SHA224 (H11)
23 Compression: Uncompressed (Z0), ZIP (Z1), ZLIB (Z2), BZIP2 (Z3)
Edit the configuration file gpg.conf and remove AES from the settings default-preference-list (and eventually from personal-cipher-preferences as well). Then adopt this change. To remove any unusable signatures, which in this case are internal ones only, use clean. Finally save and quit.
24 $ gpg --edit-key $KEYID
25 gpg> setpref
26 Set preference list to:
27 Cipher: CAMELLIA256, TWOFISH, CAMELLIA192, CAMELLIA128, CAST5, 3DES
28 Digest: SHA512, SHA384, SHA256, SHA224, RIPEMD160, SHA1
29 Compression: BZIP2, ZLIB, ZIP, Uncompressed
30 Features: MDC, Keyserver no-modify
31 Really update the preferences? (y/N) y
32 [...]
33 gpg> clean
34 [...]
35 gpg> save
9.7. Export the offline/working key
Note that after modifying the offline key, both the offline key and the working key must be exported again - just like the final step of the initial key generation process above. This also means to reset the working key's passphrase!
Export the key components to files in ASCII format. Perhaps it is a good idea to add a timestamp YYYY-MM-DD to the filenames. For the sake of brevity this document does not.
$ gpg --armor --export $KEYID > public.asc $ gpg --armor --export-secret-keys $KEYID > offline-secret.asc $ gpg --armor --export-secret-subkeys $KEYID > working-secret.asc
Ensure that the above three commands are executed successfully. After that, remove the key rings and import only the files working-secret.asc and public.asc.
$ rm pubring.gpg secring.gpg $ gpg --import working-secret.asc.asc public.asc
To set the working key's passphrase, use passwd. To remove any unusable signatures, which in this case are internal ones only, use clean. Finally save and quit.
Remove the file working-secret.asc and export the respective key components again with the modified passphrase to this file in ASCII format. Perhaps it is a good idea to add a timestamp YYYY-MM-DD to the filename. For the sake of brevity this document does not.
$ rm working-secret.asc $ gpg --armor --export-secret-subkeys $KEYID > working-secret.asc
Ensure that the above command was executed successfully.
All files must really be located on the respective storage devices before unmounting them. Finally, clean up the offline environment and shut down the system.
10. Revoke the offline/working key
Note that it is not necessary to revoke the offline key if it has expired. A new expiration date can simply be set to restore its validity. For details, see the section Extend a subkey's validity above (do no select any subkey there).
For simplicity, create an environment variable with the key ID.
$ export KEYID=2F3894F9C5688391
There are two different ways of revoking the offline key discussed in the following subsections:
10.1. Using a revocation certificate
There is a revocation certificate for the offline key which was created as in the section Create a revocation certificate above. It is assumed to be in the file revoke.asc. You need the public key, too. In case of a prior key lost, it can easily be obtained from a key server.
Warning
There is no passphrase needed to revoke a offline key.
- If the revoked offline key is published, the revocation cannot be undone.
- If the revoked offline key is not published, the revocation can be undone only if there is a backup.
Optionally import the public key.
Apply the revocation certificate to the public key by also importing it.
10.2. Using the offline key
You have the offline key available and know its passphrase.
To revoke the main key use revkey. You should almost never provide any reason for the revocation if asked. The revocation itself is a sufficient statement. Do not specify any optional description either. Finally save and quit.
1 $ gpg --edit-key $KEYID
2 gpg> revkey
3 Do you really want to revoke the entire key? (y/N) y
4 Please select the reason for the revocation:
5 0 = No reason specified
6 1 = Key has been compromised
7 2 = Key is superseded
8 3 = Key is no longer used
9 Q = Cancel
10 Your decision? 0
11 Enter an optional description; end it with an empty line:
12 >
13 Reason for revocation: No reason specified
14 (No description given)
15 Is this okay? (y/N) y
16 [...]
17 gpg> save
10.3. Final steps
Analyze the revoked public key and export it to a file revoked-public.asc in ASCII format. This file needs to be published, which normally means to send it to a key server.
1 $ gpg --list-keys $KEYID
2 pub 4096R/2F3894F9C5688391 2014-12-05 [revoked: 2014-12-05]
3 uid [ revoked] John Q. Example
4 uid [ revoked] John Q. Example <john@example.com>
5 uid [ revoked] John Example <jonny@example.net>
6 sub 3072R/8CB8E0FFDADD3834 2014-12-05 [revoked: 2014-12-05]
7 sub 3072R/3EF8C012214CDCB3 2014-12-05 [revoked: 2014-12-05]
8 $ gpg --armor --export $KEYID > revoked-public.asc
Finally, you import the file revoked-public.asc to your existing GnuPG setup(s), i.e., to all your working environment(s).
Warning
Do not remove your revoked offline key because then you will not be able to decrypt any encrypted data for this OpenPGP key or to verify any signatures made by this OpenPGP key any more.
11. Details of the exported files
The processes described in the sections above create several files in ASCII format. Their internal structure consists of a sequence of packets which can be examined by the following commands:
$ pgpdump FILE $ gpg --list-packets FILE
The first command shows a readable output and the second one gives the exact details. In both cases the OpenPGP standard RFC 4880 is handy, e. g., for looking up the various constants.
The above commands should not be run in a working environment or with any real world secret key material. Stating it more explicitly:
Warning
Never hand over control of secret key material to any third party!
- Ensure, that all sensitive information is completely destroyed without anybody being able to restore it ever.
The output of the above commands may contain sensitive information which should not be published without prior redacting! This in turn requires a good knowledge about the internals.
The following list offers the output of both commands
for the public key public.asc (pgpdump output, gpg output),
for the secret key part of the offline key /offline-secret.asc (pgpdump output, gpg output),
for the secret key part of the working key working-secret.asc (pgpdump output, gpg output),
for the revocation certificate revoke.asc (pgpdump output, gpg output),
for the revoked public key revoked-public.asc (pgpdump output, gpg output), and
for Jane Smith's certified public key jane-smith-certified.asc (pgpdump output, gpg output).
All files can also be downloaded together.
12. References
12.1. General
[GNUPG] GnuPG project, GNU Privacy Guard Manual Page, 24 June 2014
[RFC4880] Jon Callas (PGP Corporation), Lutz Donnerhacke (IKS GmbH), Hal Finney (PGP Corporation), David Shaw, Rodney Thayer, OpenPGP Message Format, RFC 4880 (obsoletes RFC 1991 and RFC 2440), November 2007
[RFC5581] David Shaw, The Camellia Cipher in OpenPGP, RFC 5581 (updates RFC 4880), June 2009
[RFC6637] Andrey Jivsov (Symantec Corporation), Elliptic Curve Cryptography (ECC) in OpenPGP, RFC 6637, June 2012
[HAC] Alfred J. Menezes, Paul C. van Oorschot, and Scott A. Vanstone, Handbook of Applied Cryptography, CRC Press, October 1996
[SCHNEIER] Bruce Schneier, Applied Cryptography Second Edition: protocols, algorithms, and source code in C, 1996.
12.2. Articles
The following entries are sorted alphabetically by their authors.
Debian Keyring Maintainers, Creating a new GPG key, 24 April 2012
Debian Wiki, Using OpenPGP subkeys in Debian development, 5 March 2014
Daniel Kahn Gillmor, HOWTO prep for migration off of SHA-1 in OpenPGP, Debian Administration Weblog entry #48, 6 May 2009
Daniel Kahn Gillmor, et. al., Including the entire fingerprint of the issuer in an OpenPGP certificate, 18-21 January 2011
Daniel Kahn Gillmor, OpenPGP user ID comments considered harmful, Debian Administration Weblog entry #97, 15 May 2013
Daniel Kahn Gillmor, gpg --ask-cert-level considered harmful, Debian Administration Weblog entry #98, 20 May 2013
Daniel Kahn Gillmor, OpenPGP Key IDs are not useful, Debian Administration Weblog entry #105, 13 Dec 2013
Ana Beatriz Guerrero López, Creating a new GPG key, 10 May 2009
Riseup, OpenPGP Best Practices
12.3. Recommendations
The following entries are ordered by their publication date.
Hilarie Orman (Purple Streak Development), Paul Hoffman (VPN Consortium), Determining Strengths For Public Keys Used For Exchanging Symmetric Keys, RFC 3766 (BCP 86), April 2004
NIST National Institute of Standards and Technology, Recommendation for Key Management, part 1 General, SP 800-57, rev. 3, July 2012
ECRYPT European Network of Excellence in Cryptology II, ECRYPT II Yearly Report on Algorithms and Keysizes, ICT-2007-216676, 30 September 2012
CRYPTREC Cryptography Research and Evaluation Committees, Reports and Ciphers list, March 2013
BlueKrypt, Cryptographic Key Length Recommendation, v27.8, 21 October 2013
Bundesnetzagentur, Jährlicher Algorithmenkatalog, 13 January 2014
ENISA European Union Agency for Network and Information Security, Algorithms, key size and parameters report - 2014, 21 November 2014
12.4. Algorithms
The following entries are ordered by the respective algorithm's name.
[AES] NIST National Institute of Standards and Technology, Advanced Encryption Standard (AES), FIPS PUB 197, 26 November 2001
[BLOWFISH] Bruce Schneier, Description of a New Variable-Length Key, 64-Bit Block Cipher (Blowfish), Fast Software Encryption, Cambridge Security Workshop Proceedings (December 1993), Springer-Verlag, 1994, pp. 191-204 (also see this overview)
[BZ2] Julian Seward, The Bzip2 and libbzip2 home page
[RFC3713] Mitsuru Matsui, Junko Nakajima (Mitsubishi Electric Corporation), Shiho Moriai (Sony Computer Entertainment Inc.), A Description of the Camellia Encryption Algorithm, RFC 3713, April 2004
[RFC2144] Carlisle Adams (Entrust Technologies), The CAST-128 Encryption Algorithm, RFC 2144, May 1997
[RFC1951] L. Peter Deutsch (Aladdin Enterprises), DEFLATE Compressed Data Format Specification version 1.3, RFC 1951, May 1996
[FIPS186] NIST National Institute of Standards and Technology, Digital Signature Standard (DSS), FIPS PUB 186-4, July 2013
[ELGAMAL] Taher A. Elgamal, A Public-Key Cryptosystem and a Signature Scheme Based on Discrete Logarithms, IEEE Transactions on Information Theory, vol. IT-31, no. 4, 1985, pp. 469-472
[RFC6090] David A. McGrew (Cisco Systems), Kevin M. Igoe, Margaret Salter (National Security Agency), Fundamental Elliptic Curve Cryptography Algorithms, RFC 6090, February 2011
[SEC1] Standards for Efficient Cryptography Group, Daniel R. L. Brown (Certicom Research), SEC 1: Elliptic Curve Cryptography, v2.0, 21 May 2009
[IDEA] Xuejia Lai, James Massey, A Proposal for a New Block Encryption Standard, EUROCRYPT 1990, LNCS 473, 1991, pp. 389-404
[FIPS180] NIST National Institute of Standards and Technology, Secure Hash Standard (SHS), FIPS PUB 180-4, March 2012
[TWOFISH] Bruce Schneier, John Kelsey, Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, Twofish: A 128-Bit Block Cipher, 15 June 1998 (also see this overview)
[RFC1950] L. Peter Deutsch (Aladdin Enterprises), Jean-Loup Gailly (Info-ZIP), ZLIB Compressed Data Format Specification version 3.3, RFC 1950, May 1996
12.5. Key servers
The following entries are ordered chronologically.
Marc Horowitz, A PGP Public Key Server, thesis
David Shaw (Jabberwocky Tech), The OpenPGP HTTP Keyserver Protocol (HKP), March 2003
Kristian Fiskerstrand, SKS keyservers: Overview of the pools
Kristian Fiskerstrand, SKS keyservers: Servers in the pool
12.6. Software
The following entries are ordered alphabetically.
Debian project, Debian GNU/Linux Live install images
GnuPG project, The GNU Privacy Guard
Kazu Yamamoto, PGPdump. There is also a PGPdump web interface on which is maintained by Stefan H. Holek.
Henk P. Penning, PGP pathfinder & key statistics, 7 Apr 2014
13. History
The OpenPGP Key Management HowTo is available in several formats which are produced from (nearly) one single source. This section gives a short overview about the milestones of the document's history. Minor fixes are omitted.
- Jun 2014: First version.
Sep 2014: Add the section Structure of an OpenPGP key. Provide informational files with details of the exported key files in a new section.
- Oct 2014: First wiki version published.
Dec 2014: Increase the size of the subkeys from 2048 bits to 3072 bits according to the ENISA Algorithms, key sizes and parameters report (see the reference section Recommendations above).