GPG Part 1: Key Management, Key Signing

Although I'm a fan of TrueCrypt for full-disk encryption and folder encryption I still rely on Gnu Privacy Guard for some of my needs. GnuPG is an Open-Source encryption tool that adheres to the OpenPGP standard. That means that this should also work on most other CLI OpenPGP-compatible packages as well. It's lightweight, cross-platform, and there are front ends that make it relatively easy to use. It can output ASCII that's easy to send in an e-mail or copy/paste into a document.

Compiling and installing GnuPG is beyond the scope of this article. That said, it's usually easy to install without compiling it, since GnuPG is available in many package repositories for Linux, BSD and OS X. Try installing gnupg, gpg or GnuPG to see if it shows up in the repository. On OpenBSD, it's as simple as running "sudo pkg_add -r gnupg". The windows package is available through the GnuPG website (linked above).

Today, I'm going to focus only on the command-line key-management features. They work the same on all platforms.

Look, I know some of you guys probably don't need to see the whole screen-shot walk-through for this. If you just want to tinker around or you already have some experience with PGP-Like tools and just want to know how to use a keyserver, sign other peoples' keys and the like, here are a few helpful commands.

Generate a new key:       gpg --gen-key
Show secret keyring:      gpg --list-secret-keys
Show public keyring:      gpg --list-keys
Export a public key:      gpg --export -a --output [filename] [hex KeyID]
Export a secret key:      gpg --export-secret-keys -a --output [filename] [hex KeyID]
Get key from keyserver:   gpg --keyserver [server] --recv-keys [hex KeyID]
Send a key to keyserver:  gpg --keyserver [server] --send-keys [hex KeyID]
Inport a key from file:   gpg --import [filename]
Sign a key:               gpg --sign-key [hex KeyID]
Editing keys (advanced):  gpg --edit-key [hex KeyID]

Generating your first key
If you've never used GnuPG before, you will have to generate a key pair. This key pair includes a public key and a secret key. The public key can be shared, and is used by anyone who wishes to send you something encrypted. Using your password-protected secret key, you can decrypt what is sent to you. This is called asymmetric crypto because a different key is used for encryption and decryption.

To generate a new key pair, use gpg --gen-key and then follow the prompts.
-bash-3.2$ gpg --gen-key
gpg (GnuPG) 1.4.9; 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.

gpg: directory `/home/axon/.gnupg' created
gpg: new configuration file `/home/axon/.gnupg/gpg.conf' created
gpg: WARNING: options in `/home/axon/.gnupg/gpg.conf' are not yet
active during this run
gpg: keyring `/home/axon/.gnupg/secring.gpg' created
gpg: keyring `/home/axon/.gnupg/pubring.gpg' created
Please select what kind of key you want:
   (1) DSA and Elgamal (default)
   (2) DSA (sign only)
   (5) RSA (sign only)
Your selection? 0
DSA keypair will have 1024 bits.
ELG-E keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048) 2048
Requested keysize is 2048 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) 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: HiR Team
Email address: team@h-i-r.net
Comment: HiR Information Report - http://www.h-i-r.net 
You selected this USER-ID:
    "HiR Team (HiR Information Report - http://www.h-i-r.net) 

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
You need a Passphrase to protect your secret key.
... Password Mumbo Jumbo ...

We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: /home/axon/.gnupg/trustdb.gpg: trustdb created
gpg: key 1ACB0D01 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   1024D/1ACB0D01 2009-03-12
      Key fingerprint = 86B3 38F5 7999 73C9 F4D3  CA65 90FC CDF3 1ACB 0D01
uid                  HiR Team (HiR Information Report - http://www.h-i-r.net)
sub   2048g/5D6C5DEE 2009-03-12

The end result is a secret key and a public key which you can view with the --list-secret-keys and --list-keys options.

Showing your keyrings
As mentioned above, the commands for listing the contents of your keyrings is simple. You can also see that my personal key (ax0n@h-i-r.net) is already in my secret and public keyring.
-bash-3.2$ gpg --list-secret-keys
sec   1024D/1ACB0D01 2009-03-12
uid                  HiR Team (HiR Information Report - http://www.h-i-r.net)
ssb   2048g/5D6C5DEE 2009-03-12

sec   1024D/7144C09F 2008-02-02
uid                  ax0n@h-i-r.net <ax0n@h-i-r.net>ssb   2048g/1622B636 2008-02-02

-bash-3.2$ gpg --list-keys
pub   1024D/1ACB0D01 2009-03-12
uid                  HiR Team (HiR Information Report - http://www.h-i-r.net)
sub   2048g/5D6C5DEE 2009-03-12

pub   1024D/7144C09F 2008-02-02
uid                  ax0n@h-i-r.net <ax0n@h-i-r.net>sub   2048g/1622B636 2008-02-02
Exporting your keys
You can export your key to an ascii file with the following command. Note, we use the hex key ID for our public key as shown above. By default, GPG exports in a binary format. the "-a" option enables "ASCII Armor" mode, which is similar to uuencode or base64 in that it takes up more characters but is more human-readable.
-bash-3.2$ gpg --export -a --output team.key 1ACB0D01
... we might as well look at the results, right? 
-bash-3.2$ cat team.key
Version: GnuPG v1.4.9 (OpenBSD)

You can upload the public key to your website and link to it. You can attach it in email, or you can just copy-and-paste it since it's ASCII Armored.

Using the --export-secret-keys option, you can similarly export your secret key. Make sure to use the -a option if you wish to have it in a text file format. AND BE SURE TO KEEP THIS KEY SAFE. If your secret key is compromised, the password protecting it is a relatively small obstacle compared to the key itself.

You can also export your public key to a keyserver. This is a public repository that lets people search for and request GPG keys for people they know. Many of these keyservers are synchronized with one another. Read about Synchronizing Key Servers here. Two SKS search links:

I'll use keys.keysigning.org in this example, since it's an SKS. To send your key to the keyserver, use the keyserver name and the hex KeyID from gpg --list-keys:
-bash-3.2$ gpg --keyserver keys.keysigning.org --send-keys 1ACB0D01
gpg: sending key 1ACB0D01 to hkp server keys.keysigning.org
Things to keep in mind when you upload to a keyserver:
  • You can upload anyone's public key to a keyserver, but you probably shouldn't without their permission. The exception is if you're going to sign someone else's key that's already on a keyserver. I'll cover that later.
  • The email addresses, names, and any other information that's part of the key will be forever stored in plain-text and indexed. This could open the email address up to being spammed, or could reveal more personal information than you'd liked. I'm just saying be careful with what you put in your key. The metadata may become public.

Importing keys
You can import keys a few different ways. The most basic is to download the key or paste and save the key as a text or ascii file. Then you import the key with --import [filename]

You can import both public and secret keys this way. GPG will auto-detect what kind of key you import.
-bash-3.2$ gpg --import phoneboy.gpg
gpg: key 597F5D2A: public key "Dameon D. Welch-Abernathy " imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg: 3 marginal(s) needed, 1 complete(s) needed, classic trust model
gpg: depth: 0  valid:   4  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 4u
Hopefully, Phoneboy does not mind me using his key as an example. He links to it from his blog (which is a good read if you're into telecom and/or security stuff)

You can also import the key from a keyserver, much like the export we described above. You do need to actually go to the keyserver to find the Hex KeyID though, or A856F98C in this example, which is Packet Storm Security's key.
-bash-3.2$ gpg --keyserver keys.nayr.net --recv-keys A856F98C
gpg: requesting key A856F98C from hkp server keys.nayr.net
gpg: key A856F98C: public key "Packet Storm Security " imported
gpg: 3 marginal(s) needed, 1 complete(s) needed, classic trust model
gpg: depth: 0  valid:   4  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 4u
gpg: Total number processed: 1
gpg:               imported: 1

The Web Of Trust
The beautiful thing about GnuPG (and other PGP-based solutions) is that you can create a "web of trust" with friends and colleagues using a keyserver. Basically, you have other GnuPG users you know sign your key. This means that they have certified that a public key belongs to you. With enough signatures on your public key, this makes it more difficult for an impostor to masquerade as you. The GNU Privacy Handbook's section on Building Your Web Of Trust explains it in more detail.

In the examples I've shown importing keys, you can see some information about depth, trust, signed, and the like. I won't get too deep into this, just enough to get you started because the above link really is a good read.

If someone sends you a public key, you can't 100% trust that it is theirs, especially if it's someone you do not know well or in person. It may belong to an imposter who has registered a convincing email address and has created their own key. Communication that you encrypt for the person you believe you're talking to could actually fall into unintended hands. It is for this reason that key signatures come in handy.

Fingerprints are cryptographic hashes that can be used to authenticate the key, but are short enough that one can scrawl them onto a napkin or the back of a business card. If you have verified the fingerprint of a person's key while you're there in person, you can verify that fingerprint against the key when you receive the key from them (or from a key server) later on. Once you verify that the key is authentic, you can "sign" it and then re-upload it to the keyserver. This means that you have personally vouched for the key's authenticity. If enough people vouch for one another's keys, the Web Of Trust is formed. Any person who may not know someone well enough to trust the key can see that several people vouch for the authenticity of the key. Perhaps one of the signers is even a mutual friend.

Key Signing
Signing is pretty easy:

You import a key from a keyserver (see example above)

You sign the key: gpg --sign-key [KeyID] (you'll be prompted for your passphrase)

You export the key back to the keyserver (see example above)

Key-Signing Parties
Throwing a Key-Signing party is a geeky way to vastly increase the size of your Web Of Trust and maybe interest others in encryption.

If you're going to try to get some people together to sign one another's keys (say, your local hackerspace, the 2600 participants, or your colleagues in the office), you should have a few things in place:
  1. Every participant's public key should be uploaded to an agreed-upon keyserver or synchronizing keyserver network.
  2. Every participant should have their hex KeyID, Name/Email and public key fingerprint written down or printed out. It's easier if participants print out several copies per page of paper (as shown in the photo) and cut them into strips to hand out to other participants.
  3. All the participants should know one another and be able to verify each other's identity. You don't need to flash Drivers' Licenses and compare them to the real name on the key, but it wouldn't hurt.
My Keysigning Party Paper just repeats the following block of text as produced by gpg --fingerprint [keyID]:
pub   rsa3072 2021-07-18 [SC] [expires: 2031-07-16]
29A2 4961 E62E DC91 AC9B 5FED 6421 2F30 5A35 5321
uid [ultimate] Noah Axon (Main GMail) <focushacks@gmail.com>
uid [ultimate] ax0n@h-i-r.net <ax0n@h-i-r.net>
sub rsa3072 2021-07-18 [E] [expires: 2031-07-16]

Participants basically make their rounds, gathering key information from every other person in the group. Then, everyone imports everyone else's key from the keyserver and verifies that the fingerprints and e-mail addresses match the ones they were given in person. After that, sign all the keys, and export the keys back to the keyserver.

Yes, this is a manually intensive process.

blog comments powered by Disqus