PGP Key Management Guide for NetBSD developers
The topic of this guide is PGP key management. It assumes that you understand the concept of asymmetric cryptography (using a private and a public key), that you know how to create and use PGP keys, and that you know how to integrate PGP support into your favourite e-mail client. It assumes that you understand the concept of signing, and encrypting, a digital message.
More information about using PGP keys can be found at:
The NetBSD project needs to be able to establish the authenticity of requests and other communications originating from project members around the world. The simplest way to do this is to establish a PGP web-of-trust amongst its members.
Typical examples of activities requiring this web of trust are:
-
the ability to sign messages to admins, e.g. for mails pertaining to the change of account details
-
the ability to sign someone else's key (to build a project-wide web-of-trust, see below), and to be able to sign an applicant's key
-
the ability to receive encrypted e-mails, e.g. in communications about security issues not to be disclosed to the outside
The most popular program for creating, managing, and using PGP keys is
probably gpg (GNU Privacy Guard), readily available as
security/gnupg
from pkgsrc.
Examples given in this document
use gnupg (rather than the alternative, pgp).
Everyone can create an arbitrary number of keys: any key with any identity; it may not be their real identity. They may upload these keys to any key server. This implies that a person could pretend to be the key owner (who is given as the user-id) although they aren't.
There are two fundamentally different concepts to address the problem of how one can establish that a certain PGP key belongs to a specific person:
-
Certification Authority (CA), usually under control of a government, verifies the identity of a person and testifies that a certain key belongs to a person (or organization). This service usually costs money.
-
Web-of-trust: whenever two PGP key holders meet, they verify their identity and sign each other's keys (see below about the significance of signing someone's key). Although not controlled by a government, if a key is signed by many persons you know you can be pretty sure about its authenticity. Crucial to the web-of-trust approach is that many key holders participate.
In a web-of-trust approach, if A has signed the key of B and B has signed the Key of C, then A can be confident about the authenticity of C. For this to work, A has to trust B not to make irresponsible signatures. The path from A to C is referred to as "chain-of-trust".
Often one encounters statements like: "I do not approve of Foo's actions, therefore I will not sign their key." or "If Foo signs their threat mail with a key that carries my signature that means that I will be held legally liable." These and similar statements are false.
What it means when you sign someone's PGP key with your signature is: "I have verified that PGP key x belongs to person y." Not more, not less.
There's no reason not to sign someone's key, provided you have carefully verified their identity.
First of all, to ensure maximum security over time, it is advisable to choose long key lengths. For maximum security it is therefore advisable to use 4096-bit RSA keys for both encrypting and signing.
% gpg --gen-key gpg (GnuPG) 1.4.12; Copyright (C) 2012 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 <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 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) <heinrichh@duesseldorf.de>" Real name: Joe Doe Email address: joe@doe.org Comment: NetBSD You selected this USER-ID: "Joe Doe (NetBSD) <joe@doe.org>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o You need a Passphrase to protect your secret key. Enter passphrase: Repeat passphrase: gpg: /home/joe/.gnupg/trustdb.gpg: trustdb created gpg: key 7CEBFEBC marked as ultimately trusted public and secret key created and signed. gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u pub 4096R/7CEBFEBC 2012-05-20 Key fingerprint = 67A7 FC80 8140 5F9B CE96 E19D E5B7 BF68 7CEB FEBC uid Joe Doe (NetBSD) <joe@doe.org> sub 4096R/6F64A1B1 2012-05-20
... and you're done!
Another question is whether a key should initially have an expiration date, or not. As the expiration date can be set or changed later on (unlike PGP 2.x keys), this question is mostly a matter of personal choice. A good reason to put an expiration date on a key is that people sometimes forget their passphrase or lose the secret key. With an expiration date, there is a drop-dead date after which the key is not going to be used.
After key creation, uids for all e-mail addresses you use should be added to your key. Don't forget to add a @NetBSD.org uid! Consider making your @NetBSD.org uid the primary uid.
As soon as you have created a PGP key pair, you may want to create a blank revocation certificate, so that you will be able to revoke your key in the event that it is compromised, or that you lose the private key (disk crash) or forget the passphrase. Be sure to store the revocation certificate in a safe place, preferably separate from the private key. Printing it out and keeping it in a safe is a good idea.
Always keep your private PGP keys on a machine to which only you have administrative access, or better yet, store your private key only on a removable USB stick (the tiniest ones sold are sufficient). Remove the USB stick whenever you are not using the key.
Protect your private PGP keys with strong passphrases.
Regularly backup your keys.
In a public/private key model, it is essential that the private key is guarded securely, while the public key is distributed as widely as possible. Anyone wanting to send you an encrypted message, or wanting to verify your signature needs your public key.
Therefore you should:
-
submit your public key to public key servers
-
commit your key to localsrc/security/publickeys/developers
The canonical key server these days is pgp.mit.edu. There are also other, newer key servers in use, e.g. keyserver.ubuntu.com. The default key server can be specified in ~/.gnupg/gpg.conf with:
localsrc/security/publickeys/developers/README describes how to commit your public PGP key to NetBSD's local source repository. Having the public PGP keys of all developers in this directory makes it very easy to import all keys (with all signatures) with just one command.
Important: Do not sign a key without checking the components of the key and without checking the authenticity. Make sure the key belongs to the person who purports to be the key owner. Keep in mind that not you, but others will rely on your signature!
Here is the recommended step-by-step procedure:
-
Prepare a "business card" type of document with the following information on your PGP key:
Key length
Key type
Key Id
Creation date
Expiration date, if any
all uids
Public key fingerprint
The output of "gpg --fingerprint" for your key provides exactly what is needed. (You may want to redirect the output of "gpg --fingerprint" into a file, duplicate the entries multiple times, and print it with "a2ps -2 --borders no -B ..." cut out the individual stripes and staple them.)
-
Carry this PGP "business card" and a solid photo ID (passport) with you when you're going to meet another developer (or any PGP key holder).
-
When you meet another developer in person, give them one of your PGP "business cards" and hand over your passport for inspection. Likewise, obtain their PGP "business card" and their passport. Verify their identity by checking their passport and compare the name on their PGP "business card" with the name mentioned in their passport.
Be extremely pedantic with checking the person's identity, doing this correctly is what signing PGP keys is all about.
It may happen that the person's name on a PGP key uid does not exactly correspond to the name in their passport. Common examples are the use of "Bill" instead of "William" or "Dick" instead of "Richard" as first names. If you're in doubt whether you should confirm the identity of a person with your signature, don't do it. Instead, ask the other party to add a new uid with their name, exactly as in the photo ID, to their key, and sign that uid.
If everything matches, make a note on their PGP "business card" that the identity check was successful (with date). This does seem an odd thing to do when you meet a single developer, but it is really the only way to reliably keep track of things at key signing parties and therefore is considered good practice.
-
When back at your computer, import the other person's public key (either from a public key server, or from localsrc). With gnupg, this is simply done with:
% gpg --import moe_pgp_key.asc
Importing the same key multiple times does not cause problems.
Importing from a public key server is done with:
% gpg --recv-key <keyid>
-
Verify that at least the following key components of the freshly imported PGP key correspond to the information on their PGP "business card":
Key type
Key length
Key ID
Key fingerprint
It is possible to generate keys for any given Key ID, and it is (due to a design flaw) even possible to create PGP keys for every fingerprint! These keys will, however, have odd key lengths.
It is currently thought impossible to generate a key for a given arbitrary tuple of (key length, key ID, key fingerprint).
If all components described above on the PGP key correspond to their counterparts on the PGP "business card" you can be sure that the public PGP key really belongs to the person that gave you the PGP "business card".
-
The remaining task prior to signing is to determine whether the other person has control over the e-mails given in all uids. To check this, generate a random number and send this number, encrypted with their key, to the other person. The task of the other person is to encrypt this random number and send it back, this time encrypted with your public key (the requirement for the encrypted return channel is to spoil any crypto-analysis attacks). It is important for the other person to sign the message they send back, so that you can verify their identify in step 7.
If you're checking multiple uids for one PGP key, keep track of which random number you send to which e-mail address.
Here is an example of this step using gnupg:
% cat >> moe@doe.org Hi Moe, please return this message to me. Please sign and encrypt it. Thanks, Joe ^D % dd if=/dev/urandom count=1 | md5 >> moe@doe.org % gpg --armor --encrypt -r moe@doe.org moe@doe.org
-
Once you've received their reply, decrypt it and check their signature. If that is successful, that concludes the necessary tests and you can sign their public key.
Using GPG, signing a key is done like this:
% gpg --edit-key <Key ID> sign
-
The last step of the procedure is to export the freshly signed PGP key and to send it to the owner.
Note: You should not directly send someone else's PGP key to a public key server, unless you received it from that key server in the first place. Although you signed it, and although it is called a "public" key, it is up to the key holder to decide how they want to distribute their key. Instead, send the signed key to the key holder and let them deal with distributing the key.
% gpg --armor --export <Key ID>
or, if you use mutt, you can take advantage of mutt's "mail-key" function:
% mutt <ESC>k To: moe@NetBSD.org Subject: Your signed PGP key Please enter the key ID: 4461CF46 <Select key> ...
Finally, you may want to update the public keys on your key ring with new signatures. This can be done using the command
% gpg --refresh-keys [--keyserver ...]
which retrieves and merges in any extra signatures that have been published on the key server since you received the key.
The Executive Committee for Membership requires that membership applicants send e-mails pertaining to their account creation signed with a PGP key which bears the signature of a current NetBSD developer. This requirement entails that the applicant must have met a current NetBSD developer prior to their account creation. At that time, their @NetBSD.org uid can not yet be signed. It is, of course, worthwhile that their @NetBSD.org uid be signed as soon as their account has been created, without requiring a new meeting. This can easily be achieved:
The key signing procedure for the applicant is performed as described above. Of course, initially only their non-NetBSD uids are signed. After their @NetBSD.org account has been created, steps 6 to 8 of the procedure are carried out for their @NetBSD.org uid. There is no need for an additional meeting with the applicant, as the correspondence of key and person have been checked previously.