Title: How To OpenPGP Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. [TOC] # Introduction # {#intro} Instructions for widely used cryptography clients. [GnuPG](#gnupg) is recommended. # GNU Privacy Guard # {#gnupg} [GnuPG](http://www.gnupg.org) is a well known open source cryptography tool with OpenPGP support. Always use the latest version. GnuPG has a good set of documentation. This guide illustrates only some important points. Please read the [manual](http://www.gnupg.org/documentation/). ## GnuPG Home ## {#home} GnuPG stores important files in a home directory including keyrings and configuration files. This may be specified using an environmental variable or on the command line. This allows different configurations and keys to be used. For example: ::console $ gpg --homedir /home/alice/keys --list-keys It is more typical to rely on the default. For \*nux (linux, BSD, MaxOSX, Solaris, AIX) this is:. :::shell $HOME/.gnupg ### How To Switch Home ### {#switch-home} The home can also be set using an envionmental variable. This allows a different configuration and keyring to be selected for the duration of the command line session. This is useful when [practicing](release-signing.html#safe-practice) as well as when using multiple keyrings. For example, to set home directory to `alice` when using Linux: :::console $ export GNUPGHOME=alice When switching key rings, check that the required keyring has been selected by examining the secret keys. For example: :::console $ gpg --list-secret-keys alice/secring.gpg ----------------- sec 4096R/E2B054B8 2009-08-20 uid Alice Example (EXAMPLE NEW KEY) ssb 4096R/4A6D5217 2009-08-20 ## Configuration ## {#configuration} GnuPG supports a wide range of configuration options. These can be specified on the command line but it is usually more convenient to set them in the `gpg.conf` file. By default, this is located in the [GnuPG Home](#home) directory. ## How To Avoid SHA-1 ## {#sha1} Use of SHA-1 should now be [avoided](release-signing.html#sha1). Until [SHA3](release-signing.html#sha3) is available, `SHA512` or `SHA256` should be used instead. `SHA512` is stronger than `SHA256`. Though some old clients lack `SHA512` support, switching to `SHA512` is recommended since it is more likely to be strong enough bridge the gap until `SHA3`. ### Setting Defaults ### {#sha-defaults} To configure `gpg` to avoid SHA-1 edit the options in [gpg.conf](#configuration). Options need to be added (or - when they exist - the existing values replaced) for: - `cert-digest-algo` - the certificate digest used when linking into the [web of trust](release-signing.html#link-into-wot) - `personal-digest-preferences` - the digest used for [signing messages](release-signing.html#detach-sig) - `default-preference-list` - the default algorithm preferences for [new keys](release-signing.html#generate) To use `SHA512` (recommended): :::text personal-digest-preferences SHA512 cert-digest-algo SHA512 default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed To use SHA256: :::text personal-digest-preferences SHA256 cert-digest-algo SHA256 default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed ### Setting Preferences For Existing Keys ### {#key-prefs} The digest preferences for each key are set (from the [configuration defaults](#sha-defaults) ) when the key is generated. Once the configuration has been updated to avoid SHA-1, all new keys generated will use these defaults. All existing private keys in the ring need to updated to indicate that stronger hashes are preferred. For each public-private key pair (generated with the previous defaults): :::console $ gpg --edit-key F8B7B4FD gpg (GnuPG) 1.4.9; Copyright (C) 2008 Free Software Foundation, Inc. This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the file COPYING for details. Secret key is available. pub 1024D/F8B7B4FD created: 2009-08-12 expires: 2009-09-11 usage: SC trust: ultimate validity: ultimate sub 1024g/D55BD150 created: 2009-08-12 expires: 2009-09-11 usage: E [ultimate] (1). Example Key (NOT FOR DISTRIBUTION) Command> showpref [ultimate] (1). Example Key (NOT FOR DISTRIBUTION) Cipher: AES256, AES192, AES, CAST5, 3DES Digest: SHA1, SHA256, RIPEMD160 Compression: ZLIB, BZIP2, ZIP, Uncompressed Features: MDC, Keyserver no-modify Command> setpref SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed Set preference list to: Cipher: AES256, AES192, AES, CAST5, 3DES Digest: SHA512, SHA384, SHA256, SHA224, SHA1 Compression: ZLIB, BZIP2, ZIP, Uncompressed Features: MDC, Keyserver no-modify Really update the preferences? (y/N) y You need a passphrase to unlock the secret key for user: "Example Key (NOT FOR DISTRIBUTION) " 1024-bit DSA key, ID F8B7B4FD, created 2009-08-12 pub 1024D/F8B7B4FD created: 2009-08-12 expires: 2009-09-11 usage: SC trust: ultimate validity: ultimate sub 1024g/D55BD150 created: 2009-08-12 expires: 2009-09-11 usage: E [ultimate] (1). Example Key (NOT FOR DISTRIBUTION) Command> save Then upload the modified public key to a public keyserver. For example: :::console $ gpg --send-keys F8B7B4FD ## How To Generate A Strong Key ## {#generate-key} The weaknesses found in [SHA-1](release-signing.html#sha1) threaten all DSA keys and those RSA keys with length less than 2048 bits. Though no realistic attack against those keys have been made public and these keys continue to be useful (and do not need to be revoked), no new keys should be generated which are exposed to this weakness. The next generation of [OpenPGP](release-signing.html#openpgp) will use [SHA-3](release-signing.html#sha3) when this is ready. It is uncertain how long this process will take. It is likely that 2048 bit RSA keys with SHA256 hash will be strong enough for this interim period - but not certain. For those with 2048 bit RSA keys, the best advice is to wait (after [switching](#sha1) to SHA256 or SHA512, of course). All new keys generated should be RSA with at least 4096 bits. Though 8192 bit keys are stronger, they are slower and may be incompatible with some older clients. For the present, 4096 bit RSA should be strong enough for code signing at Apache. To generate RSA keys with length more than 4096 bits, some changes to the source are [needed](http://www.jroller.com/robertburrelldonkin/entry/gnupg_8192bit_rsa_keys) then the procedure for 4096 bits can be followed. ### Install And Configure GnuPG ### {#key-gen-install-latest-gnupg} [GnuPG](http://www.gnupg.org) comes in two flavours: - `1.x` (well known and portable version) - `2.x` (feature enhanced) To easily generate a 4096 bit RSA signing and encryption key pair with strong digests, use GnuPG version: - `2.0.12` (or higher) - `1.4.10` (or higher) Once generated, this key can be used with the widely available `1.4.9` and `2.x` releases. If the right version of GnuPG is not currently distributed with your platform, it needs to be [installed](http://www.gnupg.org/download/index.en.html). Note that this version is only required for key generation. So, replacing the version distributed with your platform is not necessary. The new version may be installed just into a working directory just to generate the new key. Start by checking that the installation has worked and that the version is correct, either :::console $ gpg --version gpg (GnuPG) 1.4.10 Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Home: ~/.gnupg Supported algorithms: Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA Cipher: 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256 Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224 Compression: Uncompressed, ZIP, ZLIB, BZIP2 or :::console $ gpg2 --version gpg (GnuPG) 2.0.12 libgcrypt 1.4.4 Copyright (C) 2009 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Home: ~/.gnupg Supported algorithms: Pubkey: RSA, ELG, DSA Cipher: 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256 Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224 Compression: Uncompressed, ZIP, ZLIB, BZIP2 Now check that the configuration file is [setup to avoid SHA-1](#sha1). ### Generate New Key ### {#key-gen-generate-key} A new key generation option - *RSA and RSA* - was introduced in ( `2.0.12` and `1.4.10` ). This is now the default. [RSA](release-signing.html#rsa) keys are used for both encryption and signing. Longer key lengths are available. This option should be selected when generating new keys. Follow the recommendations about [user ID](release-signing.html#user-id) and [comment](release-signing.html#key-comment). Use a strong [passphrase](release-signing.html#passphrase). Follow either :::console $ gpg --gen-key gpg (GnuPG) 1.4.10; Copyright (C) 2008 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) 4096 Requested keysize is 4096 bits Please specify how long the key should be valid. 0 = key does not expire = key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) Key does not expire at all Is this correct? (y/N) y You need a user ID to identify your key; the software constructs the user ID from the Real Name, Comment and Email Address in this form: "Heinrich Heine (Der Dichter) " Real name: Robert Burrell Donkin Email address: rdonkin@apache.org Comment: CODE SIGNING KEY You selected this USER-ID: "Robert Burrell Donkin (CODE SIGNING KEY) " Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O You need a Passphrase to protect your secret key. or :::console $ gpg2 --gen-key gpg (GnuPG) 2.0.12; Copyright (C) 2009 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) 4096 Requested keysize is 4096 bits Please specify how long the key should be valid. 0 = key does not expire = key expires in n days w = key expires in n weeks m = key expires in n months y = key expires in n years Key is valid for? (0) Key does not expire at all Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: Robert Burrell Donkin Email address: rdonkin@apache.org Comment: CODE SIGNING KEY You selected this USER-ID: "Robert Burrell Donkin (CODE SIGNING KEY) " Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O You need a Passphrase to protect your secret key. ### Check That SHA1 is Avoided ### {#key-gen-avoid-sha1} Check that the configuration has correctly set the key preferences to avoid SHA-1, either :::console $ gpg --edit-key 773447FD gpg (GnuPG) 1.4.10; Copyright (C) 2008 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Secret key is available. pub 4096R/773447FD created: 2010-02-16 expires: never usage: SC trust: ultimate validity: ultimate sub 4096R/436E0F7C created: 2010-02-16 expires: never usage: E [ultimate] (1). Robert Burrell Donkin (CODE SIGNING KEY) Command> showpref [ultimate] (1). Robert Burrell Donkin (CODE SIGNING KEY) Cipher: AES256, AES192, AES, CAST5, 3DES Digest: SHA512, SHA384, SHA256, SHA224, SHA1 Compression: ZLIB, BZIP2, ZIP, Uncompressed Features: MDC, Keyserver no-modify or :::console $ gpg2 --edit-key A6EE6908 gpg (GnuPG) 2.0.12; Copyright (C) 2009 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Secret key is available. pub 8192R/A6EE6908 created: 2009-08-07 expires: never usage: SC trust: ultimate validity: ultimate sub 8192R/B800EFC1 created: 2009-08-07 expires: never usage: E [ultimate] (1). Robert Burrell Donkin (CODE SIGNING KEY) Command> showpref [ultimate] (1). Robert Burrell Donkin (CODE SIGNING KEY) Cipher: AES256, AES192, AES, CAST5, 3DES Digest: SHA512, SHA384, SHA256, SHA224, SHA1 Compression: ZLIB, BZIP2, ZIP, Uncompressed Features: MDC, Keyserver no-modify The `Digest` line should list SHA-512 first and SHA-1 last. Unfortunately, OpenPGP insists that SHA-1 is offered but it should be last of the digests listed. Instructions for altering the preferences of a key can be found [here](#key-prefs). ### Final Steps ### {#generation-final-steps} When a new code signing key has been generated, a number of Apache documents now need to be updated (together with a number of other tasks).
If you are generating a key for use in a [transition](release-signing.html#transition) , there is more which should be done before updating these documents so [return to the transition instructions now](key-transition.html#ContinueAfterGeneration).
If this is a new code signing key not involved with a transition then continue to read on. 1. [Upload](release-signing.html#keyserver-upload) the new [public key](release-signing.html#public-private) to a public [keyserver](release-signing.html#keyserver) 1. Create backups by following these [instructions](#backup) 1. Follow these [instructions](#revocation-certs) to create and securely store generic [revocation certificates](release-signing.html#revocation-cert) for the new key 1. Follow these [instructions](#update) (ignoring the transition option) to create or update Apache documents. 1. Read this [guide](#wot) to the Apache use of the [web of trust](release-signing.html#web-of-trust) and make arrangements for your new key to be included at the earliest opportunity.
## How To Find A Key ID ## {#find-key-id} There are a number of ways that a key may be identified. Only one is unique: the [key ID](release-signing.html#key-id). Attackers can easily create new keys similar to yours with identical user IDs and comments. Such a public key may be introduced to your keyring when you download keys from a [public keyserver](release-signing.html#keyserver) or as part of an import. If this information is used to identify public keys then you may be misled into believing that another public key is yours. A cunning attacker may even introduce a matching secret key allowing you to sign with that key. Creating a different key with a matching identity is considered [infeasible](release-signing.html#infeasible). For all operations where precise identity matters and that identity is specified on the command line, it is recommended that the key ID is used to identify the key. Use of user ID (or other information) should be avoided. ### From A Trusted Source ### {#find-key-id-from-trusted-source} The best way to find a key ID is to obtain it directly from a trusted source. For example, from a business card obtained personally from the owner of the key. ### From The Fingerprint ### {#find-key-id-with-fingerprint} If you have a [fingerprint](release-signing.html#fingerprint) , then the key ID should be the last 8 digits. For example, the ID of the key with fingerprint: :::text FF96 6261 C995 1DDE BF34 5150 D5D2 BDB5 E2B0 54B8 should be: :::text E2B054B8 This can be confirmed by: :::console $ gpg --list-keys --fingerprint E2B054B8 pub 4096R/E2B054B8 2009-08-20 Key fingerprint = FF96 6261 C995 1DDE BF34 5150 D5D2 BDB5 E2B0 54B8 uid Alice Example (EXAMPLE NEW KEY) sub 4096R/4A6D5217 2009-08-20 ### When You Have The Secret Key ### {#find-key-id-with-secret-key} When you have the secret key then listing the secret key details allows the key ID to be read from the `sec` lines in the output. **Note** that it is possible for an attacker to introduce a new secret key into your keyring (for example, as part of an import). It is vital that you know how many secret keys each keyring should hold. If any unexpected secret keys are present, this probably indicates an attack. For example, Alice is [transitioning](key-transition.html) and so expects two secret keys in her main keyring. (The case of a single key is similar but less complex.) To list all secret keys on the keyring: :::console $ gpg --list-secret-keys alice/secring.gpg ----------------- sec 1024D/AD741727 2009-08-20 uid Alice Example (EXAMPLE OF OLD KEY) ssb 1024g/268883A9 2009-08-20 sec 4096R/E2B054B8 2009-08-20 uid Alice Example (EXAMPLE NEW KEY) ssb 4096R/4A6D5217 2009-08-20 Alice verifies that details for only two keys are listed (and so that there are no unexpected additions). The `sec` lines are: :::text sec 1024D/AD741727 2009-08-20 and :::text sec 4096R/E2B054B8 2009-08-20 The key ID forms part of the second column, to the right of the key length. So, in this case the key IDs are `AD741727` and `E2B054B8`. The [comments](release-signing.html#key-comment) help Alice identify each key. ### Otherwise ### {#find-key-id-otherwise} Unless you have the [private key](release-signing.html#public-private) or a [fingerprint](release-signing.html#fingerprint) , the only safe way to find the key ID is to ask the owner of the key using a secure communication channel. Trusting that an import contains only the owner's public key is **not recommended**. The import may contain additional public keys (either intentionally or not). So, when using an import, always verify the key ID of interest from another source. For example, a [web page with an embedded export](http://people.apache.org/~rdonkin/) should also list the key IDs of interest. ## How To Backup ## {#backup} ### Public Information ### {#backup-public} The [key ID](release-signing.html#key-id) is not confidential but without access to this information from a trusted source, substitution attacks are [feasible](release-signing.html#infeasible) (see this [discussion](#find-key-id) ). So, for each [key pair](release-signing.html#public-private) you generate, the [key ID](release-signing.html#key-id) needs to recorded in a form that makes tampering difficult. Defense in depth is the best strategy. So, it is recommended that a variety of different methods are used: - Print a hard copy of the key ID then store securely - Include the key ID on your business cards - Members should include the key ID on their Apache business cards - Include a text document containing the key ID in your [secure, tamperproof private backups](#backup-private) ### Private Information ### {#backup-private} A [private key](release-signing.html#public-private) must be kept both safe and away from attackers. If a private key is destroyed or lost then the key must be revoked and should no longer be used. Given the effort that's needed to build a strong [web of trust](release-signing.html#web-of-trust) , the private key needs to be backed up without compromising security. The best way to backup a private key is to securely archive the entire [GnuPG home](#home) by copying the contents into secure, encrypted storage. It is recommended that each archived copy is versioned and retained permenantly. Full disk encryption is the best storage solution for disks containing the private key. How to encrypt a full disc is platform dependent and is beyond the scope of this guide but this is now supported by many major platforms. A strong passphrase should be chosen. If this is not possible then strong, symmetric encryption should be used to protect a compressed archive. Again, a strong passphrase should be chosen. Instructions are available [here](#symmetric). A removable medium type with good long term storage characteristics is recommended. For example: - A small capacity, high quality USB flash drive - A CDROM It is recommended that multiple copies are created and securely stored. ## How To Export ## {#export-key} Exporting public keys is a common operation. It is rarely necessary to export a [private key](release-signing.html#public-private) and use of that operation should be kept to a minimum (see discussions [below](#export-secret-key) ).So, the unqualified term *exporting a key* almost always means *exporting a public key*. GnuPG seeks to limit accidental private key by using different operations for each export. Both operations share common options. ### Output Options ### {#export-option-output} By default, operations print their results to the command line. For example, to export all public keys (with ASCII encoding) to the command line: :::console $ gpg --export --armor The `--output` option followed by the name of a file creates that file and stores the output in it. For example, to export all public keys (with ASCII encoding) into a newly created file named `export.asc` : :::console $ gpg --export --output export.asc --armor Though most of the examples in this guide choose to output to a file, command line output is often useful (for example, the output can be piped into a second command) and is equally valid for most operations. The exception is [secret key export](#export-secret-key) which should always be done to a secure temporary file. ### Armor Option ### {#export-option-armor} The *--armor* option encodes the output using [ASCII characters only](release-signing.html#ascii). This allows the output to be easily embedded in documents and displayed on the command line. For example, to export all public keys (to the command line) encoded in ASCII: :::console $ gpg --export --armor The binary format is shorter but has few other advantages. For all uses at Apache, ASCII armor should be used. ### How To Export Public Keys ### {#export-public-key} The `--export` operation exports public keys. When no keys are specified, all public keys in the keyring will be exported. For example, to export all public keys to the [command line](#export-option-output) with [ASCII encoding](#export-option-armor) : :::console $ gpg --export --armor To export specific keys, identifiers for these keys are added to the end of the command. Keys can be identified in a number of ways but only the [key ID](release-signing.html#key-id) will definitely select a single key. This [guide](#find-key-id) discusses how to find the key ID when it is unknown. For example, to export to the [command line](#export-option-output) with [ASCII encoding](#export-option-armor) the public key with ID `AD741727` : :::console $ gpg --export --armor AD741727 ### Whether To Export Some Or All Public Keys ### {#export-all-or-some-public-keys} This is often a tricky question. An import should not be trusted for key identification (see [discussion](#find-key-id) ). So, for an import to be useful, usually the key ID of interest needs to be known. Keys used at Apache should be available through the global [public keyserver](release-signing.html#keyserver) network. Using this network, given the [key ID](release-signing.html#key-id) the public key can be downloaded. So, an export is really only useful for someone who cannot use the global keyserver network. But in this case, the import really needs to include all the public keys on the ring to maximise the chances of a trusted path being found in the [web of trust](release-signing.html#web-of-trust). The risk of exporting all keys is that those users who don't understand that an export should not be used for key identification may be mislead by the other keys exported. The risk exporting just one public key is that users may be mislead into thinking that imports are trustworthy for key identification. So, neither is a very satisfactory solution. Now that global keyserver network works so well, Apache may move away from the use of exports in the future. ### How To Export Secret Keys ### {#export-secret-key} This is a risky operation. The most vulnerable part of the system is the [passphrase](release-signing.html#passphrase) that encrypts the private key. If an attacker obtains a copy of the encrypted private key file, an attack on the passphrase is likely to be [feasible](release-signing.html#infeasible). So, it is vital that the [private key](release-signing.html#public-private) is stored securely at all times. There are very few occasions when this risk is justified. So, when people talk about exporting keys, this means the export of the *public* key only (unless the secret key is mentioned explicitly). Whenever a private key export is necessary for a task covered in this guide, the process will be described completely in the section. Use of secret key export in other circumstances is not recommended. To ensure that private keys are not accidentially exposed, GnuPG `--export` operation exports only public keys. Secret keys should **never** be exported to the command line. Instead a secure temporary file should be used which should be securely deleted after use. The [secret key transfer guide](#secret-key-transfer) illustrates one way that this can be done. ## How To Transfer A Secret Key ## {#secret-key-transfer} Start by [switching](#switch-home) GnuPG [home](#home) to the source. To export all secret keys to a temporary file ( `/tmp/new.sec` , say): :::console $ gpg --export-secret-keys --armor --output /tmp/new.sec Next import this temporary file into the target keyring. Ensure that GnuPG [home](#home) is set to the target keyring (by either [switching](#switch-home) the current session or opening a new terminal configured to use the target keyring). Then: :::console $ gpg --import /tmp/new.sec gpg: key E2B054B8: secret key imported gpg: key E2B054B8: public key "Alice Example (EXAMPLE NEW KEY) " imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1) gpg: secret keys read: 1 gpg: secret keys imported: 1 Check for *secret keys imported* in the output. Listing secret keys (for the target keyring) should now show the existance of the secret key in this keyring: :::console $ gpg --list-secret-keys alice/secring.gpg ----------------- sec 1024D/AD741727 2009-08-20 uid Alice Example (EXAMPLE OF OLD KEY) ssb 1024g/268883A9 2009-08-20 sec 4096R/E2B054B8 2009-08-20 uid Alice Example (EXAMPLE NEW KEY) ssb 4096R/4A6D5217 2009-08-20 Finally ensure that the temporary file used cannot be read. Secure deletion is recommended. For example, using [shred](http://www.linfo.org/shred.html) on Linux: :::console $ shred /tmp/new.sec $ rm /tmp/new.sec Those using encrypted `tmp` should now restart the machine. ## How To Transition From An Old To A New Key ## {#transition} If you have a short but uncompromised key and would like to [transition](release-signing.html#transition) to a longer one, follow these [instructions](key-transition.html). If your key has been compromised then you **MUST NOT** transition but [revoke](release-signing.html#revoke-key) the old key and replace with a new one immediately. **DO NOT** use a transition period. ## How To Use Revocation Certificates ## {#revocation-certs} When a private key is lost or compromised, a [revocation certificate](release-signing.html#revocation-cert) should be [distributed](release-signing.html#revoke-cert) to [publicly](release-signing.html#keyserver) [revoke the key](release-signing.html#delete-vs-revoke). In the event of a compromise or loss, it is best to create a new revocation certification including the particulars of the case. Since this may not always be possible, generic revocation certificates should be created for each new key pair [generated](#generate-key) and [securely stored](release-signing.html#revocation-certificate-storage). ### Generic Revocation Certificates ### {#revocation-cert-generic} When a new [key pair](release-signing.html#public-private) is created, generic revocation certificates for that key pair should be generated and securely stored. It is recommended that a certificate is generated (following the instructions in the next section) for each appropriate revocation reason type: - No reason specified - Key has been compromised - Key is no longer used Note that *Key is superseded* is not appropriate for a new key since it is not possible to know which key will replace it. Generic revocation certificates need to be stored safe but securely until needed. If an attacker obtains a revocation certificate then they will be able to deny your use of the key by publishing it. The private key is not compromised by this act and this limits the harm they can do. However, a new key will need to be generated to replace the one that has been revoked, the [web of trust](release-signing.html#web-of-trust) rebuilt and the Apache revocation process [followed](release-signing.html#revoke-cert). It is recommended that these certificates are stored directly onto media with good long term stability and secure (for example, an encrypted file system on a top end USB drive or a CDROM). Hard copies should be printed. Copies should be stored with trusted third parties. ### How To Generate A Revocation Certificate ### {#revocation-cert-gen} Revocation certificates include a small amount of additional information. The certificate includes one of four machine readable reason types: - No reason specified - *a catch all category* - Key has been compromised - *this should also be used when there is reason to believe that the key may have been compromised (for example, when a storage device containing the private key has been lost)* - Key is superseded - *the comment should suggest the replacement key* - Key is no longer used - *useful when the key has been destroyed and so a generic revocation prepared earlier must be used* The certificate also includes a human readable comment. This comment should be used to explain the reason why the key was revoked. This allows an appropriate response to be formulated by those effected by the revocation. When a key has been compromised, lost or superseded, when possible a new certificate should be generated containing a comment explaining the situation. For example, an [ASCII armored](release-signing.html#ascii) (for ease of handling) revocation certificate for key `AD741727` can be generated as follows: :::console $ gpg --output revoke-AD741727.asc --armor --gen-revoke AD741727 sec 1024D/AD741727 2009-08-20 Alice Example (EXAMPLE OF OLD KEY) Create a revocation certificate for this key? (y/N) y Please select the reason for the revocation: 0 = No reason specified 1 = Key has been compromised 2 = Key is superseded 3 = Key is no longer used Q = Cancel (Probably you want to select 1 here) Your decision? 1 Enter an optional description; end it with an empty line: > THIS IS AN EXAMPLE MESSAGE DESCRIBING THAT THIS KEY WAS COMPROMISED > Reason for revocation: Key has been compromised THIS IS AN EXAMPLE MESSAGE DESCRIBING THAT THIS KEY WAS COMPROMISED Is this okay? (y/N) y You need a passphrase to unlock the secret key for user: "Alice Example (EXAMPLE OF OLD KEY) " 1024-bit DSA key, ID AD741727, created 2009-08-20 Revocation certificate created. 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! When preparing generic certificates (for use if the [private key](release-signing.html#public-private) is unavailable), the comment cannot include the specifics and so should indicate this. This process for generating a generic certificate is identical but a different comment should be used. For example, an [ASCII armored](release-signing.html#ascii) (for ease of handling) revocation certificate for key `AD741727` can be generated as follows: :::console $ gpg --output revoke-AD741727.asc --armor --gen-revoke AD741727 sec 1024D/AD741727 2009-08-20 Alice Example (EXAMPLE OF OLD KEY) Create a revocation certificate for this key? (y/N) y Please select the reason for the revocation: 0 = No reason specified 1 = Key has been compromised 2 = Key is superseded 3 = Key is no longer used Q = Cancel (Probably you want to select 1 here) Your decision? 1 Enter an optional description; end it with an empty line: > This revocation certificate was generate when the key was created. > Reason for revocation: Key has been compromised This revocation certificate was generate when the key was created. Is this okay? (y/N) y You need a passphrase to unlock the secret key for user: "Alice Example (EXAMPLE OF OLD KEY) " 1024-bit DSA key, ID AD741727, created 2009-08-20 Revocation certificate created. 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! ## How To Use Symmetric Encryption ## {#symmetric} GnuPG supports symmetric (in addition to public key) cryptography but the ciphers available sometimes differ. Use `gpg --version` to discover which are available in the current installation. For example, :::console $ gpg --version gpg (GnuPG) 1.4.9 Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Home: alice Supported algorithms: Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA Cipher: 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224 Compression: Uncompressed, ZIP, ZLIB, BZIP2 So, in this case, the available ciphers are: :::text 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH Note that most of the ciphers early on the list are weak. This is typical. So, it is recommended that a strong cipher is specified on the command line. For example, to encrypt a document `INPUT_FILENAME` using `AES256` (a strong cipher) and output to file `ENCRYPTED_FILE` : :::console $ gpg --cipher-algo AES256 --output ENCRYPTED_FILE --symmetric INPUT_FILENAME When prompted for a [passphrase](release-signing.html#passphrase) , chose a strong one. The file format contains meta data including the cipher used. So to decrypt `ENCRYPTED_FILE` into `OUTPUT_FILE` use: :::console $ gpg --output OUTPUT_FILE --decrypt ENCRYPTED_FILE # How To Update Apache Documents With Details Of A New Key # {#update} For the new key, both the [fingerprint](release-signing.html#fingerprint) and the [public key](release-signing.html#public-private) export will be needed more than once. Creation instructions are repeated below for each case but you may find it more convenient to create, store then reuse the results. ## pgpkey ## {#pgpkey} The `.pgpkey` file in your home directory on [people.apache.org](http://people.apache.org) should contain an [ASCII armored](release-signing.html#ascii) [public key](release-signing.html#public-private) [export](release-signing.html#export) of all the keys which you use for signing Apache releases. To create an [ASCII armored](release-signing.html#ascii) [export](release-signing.html#export) : - When using a [transition](release-signing.html#transition) , follow these [instructions](key-transition.html#transition-export). - Otherwise gpg --output *KEYID*.asc --armor --export *KEYID* (where *KEYID* is the [key ID](release-signing.html#key-id) of the key to be exported). See this [guide](#export-key) for more details. The result should then be `scp` 'd into place in your home directory on [people.apache.org](http://people.apache.org) and installed in your [LDAP profile](https://id.apache.org) (which will make it available on [https://people.apache.org/keys/](https://people.apache.org/keys/)). ## Publish Public Key ## {#publish-in-web-space} Note: signing keys must also be uploaded to a public key server, see [http://www.apache.org/dev/release-signing.html#keyserver-upload](http://www.apache.org/dev/release-signing.html#keyserver-upload) A reliable, permanent URL for your new public key is useful. Your Apache web space is an ideal location for this. It is recommended that you copy an [ASCII armored](release-signing.html#ascii) [public key](release-signing.html#public-private) [export](release-signing.html#export) (see instructions later, or use documents you created earlier) into the `public_html` subdirectory of your home on [people.apache.org](http://people.apache.org). The suffix `.asc` is conventional for ASCII armored public key exports. So, for example, `A6EE6908.asc` is a reasonable choice for the export of key `A6EE6908`. Record the URL (for example `http://people.apache.org/~rdonkin/A6EE6908.asc` ) for use later in your [FOAF](#foaf). If your Apache home page contains details of your keys (recommended) update the [fingerprints](release-signing.html#fingerprint) and the [ASCII armored](release-signing.html#ascii) [public key](release-signing.html#public-private) [export](release-signing.html#export). Any browser with a suitable [OpenPGP](release-signing.html#openpgp) plugin (for example, [Firefox](http://www.mozilla.com/firefox/) with [FireGPG](http://www.getfiregpg.org) ) will be able to download the key into the local keyring. For example, [this home page](http://people.apache.org/~rdonkin/) contains a section with fingerprints and a link to the export. At the bottom, the export has been inlined allowing browsers with [OpenPGP](release-signing.html#opengpg) support to import the keys. To create an [ASCII armored](release-signing.html#ascii) [public key](release-signing.html#public-private) [export](release-signing.html#export) : - When using a [transition](release-signing.html#transition) , follow these [instructions](key-transition.html#transition-export). - Otherwise this [discussion](#export-key) describes how to export public keys To find the [fingerprint](release-signing.html#fingerprint) for a key: - When using a [transition](release-signing.html#transition) , follow these [instructions](key-transition.html#transition-fingerprints). - Otherwise `gpg --fingerprint` ## Add Keys To FOAF ## {#foaf} If you are included in the [Apache community pages](http://people.apache.org/) ( [recommended](http://people.apache.org/foaf/index.html) ), update your FOAF with the new fingerprints. To find the [fingerprint](release-signing.html#fingerprint) for a key: - When using a [transition](release-signing.html#transition) , follow these [instructions](key-transition.html#transition-fingerprints). - Otherwise `gpg --fingerprint` Ensure that each `pubkeyAddress` points to the new export [uploaded into your Apache home web space](#publish-in-web-space). When [transitioning](release-signing.html#transition) , include one entry for the old and one for the new key. The same URL can be used for both since the target should be the [dual export](key-transition.html#transition-export) [uploaded earlier](#publish-in-web-space). For example, for keys A6EE6908 (new) and B1313DE2 (old): :::xml A6EE6908 597C729B02371932E77CB9D5EDB8C082A6EE6908 B1313DE2 EA6141E8E49E560C224B2F74D5334E75B1313DE2 ## Remember To Update KEYS On Next Release ## {#update-KEYS} Projects maintain [KEYS](release-signing.html#keys-policy) files containing the public keys used to sign Apache releases. These documents need not be updated immediately, but they **MUST** be updated with an export before any release is published using the new key. To create an [ASCII armored](release-signing.html#ascii) [export](release-signing.html#export) : - When using a [transition](release-signing.html#transition) , follow these [instructions](key-transition.html#transition-export). - Otherwise this [discussion](#export-key) describes how to export public keys If an older export is already contained in the `KEYS` file then that should be removed. ## (Members Only) Update Details ## {#members-details} [Members](http://www.apache.org/foundation/members.html) should add the new key to their details stored in subversion. Update your Apache business card with fingerprints (see `Cards` directory in members area in subversion). Place a new order for cards. # How To Use The Web Of Trust # {#wot} A link to a new key from a [web of trust](release-signing.html#web-of-trust) is made when a key that is part of that network signs the new key. Each link is only one way. By signing a key, you indicate that you have verified the identity of the owner of that key. Only when the owner of that key also signs your key are links established in both directions. So, whenever the owner has suitable identification, expect the owner to ask you to sign their key in return. These directional links can be used to establish trust in the identity of a key whose owner you haven't met. ## How To Verify Identity ## {#wot-verifying-links} This process is usually automated but the best way to understand the process is to work through a manual example. Those who already understand should [skip forward](#apache-wot). ### Example - The Hard Way ### {#wot-manual-example} For example, take Alice, Bob and Charlie. Alice has verified Bob's identity in person. Bob has verified Charlie's identity in person but Alice has never met Charlie. So - Bob's key has been signed by Alice's key - Charlie's key has been signed by Bob's key Alice has obtained a file ( `document` , say) which may have been created by Charlie, and a detached signature for that file ( `document.asc` , say). Alice wishes to discover whether this file has been signed by Charlie. The basic idea is easy. If Alice has verified Bob's identity and trusts Bob to verify the Charlie's identity before signing, then Alice should be able to work out whether the key which has been used to sign the file is owned by Charlie. Alice starts by verifying the signature: :::console $ gpg --verify document.asc gpg: Signature made Wed Sep 9 14:33:12 2009 BST using RSA key ID 8F8A2525 gpg: Can't check signature: public key not found This indicates that the key used to create this signature is missing from Alice's keyring. This is not unexpected. So, Alice add the public key, perhaps by using a public key server or by importing an export. This time: :::console $ gpg --verify document.asc gpg: Signature made Wed Sep 9 14:33:12 2009 BST using RSA key ID 8F8A2525 gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 1 signed: 1 trust: 0-, 0q, 0n, 0m, 0f, 1u gpg: depth: 1 valid: 1 signed: 0 trust: 1-, 0q, 0n, 0m, 0f, 0u gpg: Good signature from "Charlie (EXAMPLE ONLY NOT FOR DISTRIBUTION) " gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: B7F6 17FA 4DEF E61F 37A4 7463 41F4 40D4 8F8A 2525 This output indicates that this key says that it is created by Charlie. This is a reasonable start but is easily faked. Alice examines the signatures on this key: :::console $ gpg --list-sigs 8F8A2525 pub 2048R/8F8A2525 2009-09-09 uid Charlie (EXAMPLE ONLY NOT FOR DISTRIBUTION) sig 3 8F8A2525 2009-09-09 Charlie (EXAMPLE ONLY NOT FOR DISTRIBUTION) This key is signed only by itself. This is not indicative. Unless all keys in the ring have been refreshed, it is possible that a signature has been made but is missing from the ring. Alice refreshes the keys on the ring then verifies once more: :::console $ gpg --list-sigs 8F8A2525 pub 2048R/8F8A2525 2009-09-09 uid Charlie (EXAMPLE ONLY NOT FOR DISTRIBUTION) sig 3 8F8A2525 2009-09-09 Charlie (EXAMPLE ONLY NOT FOR DISTRIBUTION) sig 1B912854 2009-09-09 Bob___ (EXAMPLE ONLY NOT FOR DISTRIBUTION) The key now has a signature from Bob's key - or so says the key. But Alice has met Bob. So, listing the signatures for that key that may - or may not - be owned by Bob: :::console $ gpg --list-sigs 1B912854 pub 2048R/1B912854 2009-09-09 uid Bob___ (EXAMPLE ONLY NOT FOR DISTRIBUTION) sig 3 1B912854 2009-09-09 Bob___ (EXAMPLE ONLY NOT FOR DISTRIBUTION) sig 81590910 2009-09-09 Alice (EXAMPLE ONLY NOT FOR DISTRIBUTION) Alice finds it signed by `81590910` - the master key for this keyring. Alice can therefore trust that Charlie has signed the file provided so long as Alice trusts Bob to verify Charlie's identity. ### Automated Trust ### {#wot-automated} Most clients allow automation of this process of transitive trust resolution. This is more easier and convenient than by hand but clients differ both in the model adopted. Some clients (including GnuPG) are highly configurable (allowing different trust models to be used) and allow finely grained control over trust placed in each signed key. For more details see the [The GNU Privacy Handbook](http://www.gnupg.org/gph/en/manual.html). ## Code Signing Keys And The Web Of Trust ## {#apache-wot} It is vital that Apache code signing keys are linked into a strong [web of trust](release-signing.html#web-of-trust). This allows independent verification of the fidelity of Apache releases by anyone strongly linked to this web. In particular, this enables to two important groups to independently verify releases: - The Apache Infrastructure Team - Downstream packagers The Apache web of trust is reasonably well connected to the wider open source web of trust. So though every opportunity should be taken to link into wider networks the most important action needs to be to plan to exchange signatures with other Apache committers. ## How To Link Into The Apache Web Of Trust ## {#apache-wot-link} The process is the same (as explained below) but the people are different: this means arranging to meet in person with Apache committers. For a global distributed organisation like Apache, this is not always easy and usually takes some planning. ### Keysigning At ApacheCon ### {#wot-apachecon} A major [keysigning party](release-signing.html#key-signing-party) is organised by Apache at every [ApacheCon](http://apachecon.com/). This is a great way to collect dozens of signatures. ### Keysigning At Other Apache Events ### {#wot-apache-other-events} Other Apache events may also hold keysigning parties (and most will if asked). Typically, these will be smaller and less informal. Subscribe to the community list (see committer documentation) to keep in touch. ### Informal Meetings ### {#wot-apache-party} Smaller, informal meetings are also an opportunity to swap keys (as well as gossip) with other committers. Subscribe to the party list (see committer documentation) to find out about informal meetings. When you travel, take advantage of this opportunity to meet up with other Apache committers by posting to party list. The [committer map](http://people.apache.org/map.html) shows locations for many committers. If there are committers near you, organise an informal meetup. ## How To Link Into A Public Web Of Trust ## {#wot-link-in} In short, expect that: - this will involve a face-to-face meeting - that some form of identification will be demanded - you will be asked to verify their identity and sign their public key in exchange Bring the key [fingerprint](release-signing.html#fingerprint) but keep the private key safely at home. ### Be Prepared ### {#wot-public-preparations} A small amount of preparation (before attending technical conferences or meetings) will allow keys to be exchanged (if the other person is suitably prepared) or your key signed if the opportunity presents itself. All that is required is suitable identification and the [public key fingerprint](release-signing.html#fingerprint) (which can can be conveniently printed onto a small card). ### Keysigning Parties ### {#wot-public-keysigning} The most effective way to achieve this is to attend a [key signing party](release-signing.html#key-signing-party). Most open source organisations (including Apache) organise parties at their conferences. At other events, it may be possible to organise one. Expect: - To bring identification - To bring a hard copy of your key's [fingerprint](release-signing.html#fingerprint) - To supply the key ID or public key to the organiser before the party - To check that the [fingerprint](release-signing.html#fingerprint) (for your key) supplied by the organiser matches your hard copy - To confirm this to those present Do **NOT** bring your private key. This **MUST** stay safe and secure at all times. Wait until the conference has finished and you have returned home before signing keys. For more information, see this [guide](http://www.cryptnet.net/fdp/crypto/keysigning_party/en/keysigning_party.html).