GnuPG - An Overview

by Rick Moen

Revised: Wednesday, 2008-05-14

Master version will be at http://linuxmafia.com/faq/Security/gnupg.html, and I'll try to improve it there.


Scope of this talk: This talk will cover the general use of GnuPG, as well as some specifics relevant to a one-time customer of mine. That firm's IS Dept. uses GnuPG as a general delivery vehicle for security-token data to employees outside. I won't be covering those tokens and the systems they're for, just GnuPG and related systems.


History of public-key cryptography:

Symmetric:

1466: Symmetric (or secret-key) cryptography invented by architect Leon Battista Alberti of Italy. Requires shared secret (key), which must be distributed separately -- logistical problem. (Symmetric crypto is used in GnuPG for the "session key", which gets transmitted encrypted using the other type.) Called symmetric because you use the same key for encrypting and decrypting. Examples: Blowfish (GnuPG's default), IDEA, 3DES, AES (Rijndael), German WWII Enigma code, PKZ's "Bass-o-Matic".

Asymmetric:

1970-71 Asymmetric (or public-key) crypto invented in secrecy by James H. Ellis of the British Secret Intelligence Service (technically, GCHQ). Ellis was deprived of credit for this until recently by the UK's Official Secrets Act.

1973: C.C. Cocks of UK GCHQ is claimed to have independently invented a public-key algorithm similar to RSA (again, in secret): http://www.cesg.gov.uk/site/publications/media/notense.pdf

1976: Public-key crypto re-invented by Whitfield Diffie and Martin Hellman ("DH") of Stanford U.

1977: Slightly more-practical method invented by Rivest, Shamir, and Adleman (RSA) at MIT, and published in Scientific American. Rights held (mostly) by MIT. And the game begins.

Enter PGP/PGPi:

1991. PGP 1.0 ("Pretty Good Privacy") released by Philip K. Zimmerman (PKZ), infringing two patents and a copyright, not to mention USA "munitions" regulations. PGPi developed in parallel by crazy Norwegian Ståle Schumacher Ytteborg to get around the legal problems for non-USA/Canada users (based on PKZ code, but includes some variant crypto libraries). Licence on both was initially GPL through 2.6.3a, and then became gratis non-commercial usage. Later, PKZ sold his company (PGP, Inc.) and his software's copyright to Network Associates, Inc.; versions after 6.5.8 became binary-only and MacOS/Win32-only. In early 2002, development was curtailed.

In June, 2002, a group of old-time PGP experts bought PKZ's firm back from Network Associates, Inc., renamed it PGP Corporation, and resumed development. Current version (8.0) remains binary-only and proprietary.

What does it do? People can send you secret information by encrypting it with your public key. You can authenticate information as coming "from you" by signing it with your private key. A company might use the first of these two functions -- using the GnuPG package instead of PGP -- to send information that must be kept secret, when we're outside the company network (e.g., sending SFS passphrases and one-time password lists or seeds).

PGP uses symmetric (secret-key) techniques to encode the messages it protects, and asymmetric (public-key) techniques to safely transmit the necessary symmetric key used for that session.

1996. IETF document RFC 1991 "PGP Message Exchange Formats" defines clearsigning PGP e-mail as an Internet standard, based on PGP 2.x. IETF document RFC 2015 "MIME Security with Pretty Good Privacy (PGP)" then extends this to define a MIME-based alternative to clearsigning.

OpenPGP:

1998. IETF document RFC 2440 "OpenPGP Message Format" defines OpenPGP as an Internet standard. Tries to improve interoperability. (Dominant versions PGP 2.6.x, PGP 5.0, and PGPi 5.x had accumulated sundry incompatibilities.) This was then extended (2001) by IETF document RFC 3156 "MIME Security with OpenPGP" to define a MIME-based alternative, compatible with the PGP one (RFC 2015).

GnuPG:

1999: Werner Koch in Germany releases GnuPG (aka gpg, short for "GNU Privacy Guard") as an OpenPGP implementation. GPL-licensed. Only significant compatibility issue is that it omits the IDEA symmetric algorithm (US-patented by Ascom AG of Switzerland until 2010). This compatibility issue (and a few others like it) will not be a problem for new deployments.

New deployments should standardise on GnuPG as a PGP-equivalent, invoking it as if it were PGP, generally (though there are some differences, and in particular the command-line options are not interchangeable).

(One can add IDEA support to GnuPG, by retrieving, compiling, and installing the extension for that program, and informing GnuPG of its presence by adding "load-extension idea" to ~/.gnupg/options . But you will encounter IDEA keys rarely if ever (basically, only from people using antique PGP 2.x releases). Also, please be advised that using IDEA in the USA may entail legal problems until May 25, 2010.)


How to Use GnuPG:

Generating Your Keys & Revocation Certificate:

"gpg --gen-key" Accept default option 1, to generate both DSA and ElGamal keys. Accept default keysize (1024 bits). It doesn't hurt to have no key expiration (default choice), because you can always change this. You'll be asked for a symmetric-crypto "passphrase" (some phrase you can easily remember): It will be used to encrypt the copy of your private key stored on your hard drive, and you'll be prompted for it any time you want to use your private key. GnuPG will work for a while: You'll be prompted to generate random activity with your mouse and/or keyboard, during the time it's working. Eventually, it will say it's finished, resulting in:

~/.gnupg/pubring.gpg
~/.gnupg/secring.gpg

These will hold your public and private (secret) keys, respectively. Other keys (e.g., from other people you deal with) can be added to them, which is what makes them "keyrings". To list the contents of your public keyring:
"gpg --list-keys"

To list the contents of your private (secret) keyring:
"gpg --list-secret-keys"

Your keys are tied to your name and e-mail address. If either changes, you will need a new set of keys.

Also immediately do:
"gpg --output revoke.asc --gen-revoke yourusername" (You can use your e-mail address, instead of your username.)

This will create ~/.gnupg/revoke.asc , your "revocation certificate", which you'll be able to publish in the future if you ever need to get the word out that your keys should no longer be trusted.

Congratulations! Aside from key-signing, you're now pretty much done with having to use GnuPG from the command line.

(Just for your information, keyrings are stored in a human-hostile binary format, necessitating arcane formulas to "export" them from keyring to ASCII and "import" them from ASCII to keyring. You'll see references to "armoring" keys, which means exporting them to "radix-64 format", which is a type of ASCII conversion similar to uuencoding. Don't worry about this for now.)

Key sizes: Defaults are fine for any likely purpose, as weaknesses in the system will probably lie elsewhere. Longer keys = slower operation. If you genuinely need 80 years of secrecy, pay that price, and hire a staff cryptographer. Otherwise, don't.

Signing GnuPG Keys ("Key-Signings" or "Key-Signing Parties"):

Public-key cryptography made possible many tricks not previously available, but retains the Achilles Heel of all cryptography: key distribution (the flip side being key tampering). How do you know that a public key supposedly from your friend Alice really belongs to her? Advantage of "public key" methods is that the key can be public, but you still have the problem of proving it's a real, still-valid key for the right person.

Obvious way is to get it directly from Alice, but she may be around the world. How about if your friend Bob certifies that it's really Alice's? Or how about if your friend Carol certifies Bob's certification of Alice's key? Alice furnishes her key to Bob, who signs it with his key. Carol signs Bob's key with hers. And you know Carol, and have signed her key. These chains of signing build a "web of trust".

Trust is subjective: You trust other people's certification of other people's keys to the degree you think they're reliable in handling keys. (GnuPG has a way for you to privately mark such certifications that your trust level of that person is "none", "unknown", "marginal", or "full", but we won't get into that, here.)

Groups of individuals occasionally hold in-person keysigning "parties" to build and extend the "web of trust".

Here's a key procedure from a key-signing party held by the "Bay Area Debian" group (http://bad.debian.net/list/2001-June/001237.html):


1. Send your key to the key-signing party organizer. You can get your public key out of your keyring by doing a command like this:

gpg --export --armor "your@email.address" > yourname.asc

Then, e-mail yourname.asc to the signing party's organizer.
Please, don't encrypt the mail you send to the organizer.

2. Print out a copy of your key fingerprint. This is for you to carry around. You can get a copy of your key fingerprint by doing this:

gpg --fingerprint "your@email.address" > yourname.fp

...and then print yourname.fp out.

3. Make sure you have valid ID, like a passport or driver's license, that has the same name as on your key.

At the Party

0. Get a copy of the keyring printout from the organizer.

1. For as many people as you can, do identification (see below). (We'll probably have a semi-formal, around-the-room session to do mass identification, which I'll explain at the event. It worked pretty well last time.)

2. Meet people and have fun.

Identification

Here are the steps that happen when Alice is going to identify Bob.

Alice needs: keyring printout, pencil or pen.
Bob needs: fingerprint printout, ID.

0. Bob presents a picture ID, such as a driver's license or passport.

1. Alice marks on her keyring printout a single check next to Bob's name, to indicate "identified."

2. Bob reads his fingerprint printout to Alice. Alice follows along on her keyring printout.

3. If the fingerprint that Bob reads matches the fingerprint Alice has on her printout, she makes a second check, indicating "fingerprint matches."

Of course, it's nice if they then switch roles, and Bob identifies Alice.

After the Party

0. Key signers download the party keyring from the URL I'll publish.

1. For each name on their keyring printout that has two checks (identified, fingerprint matches), sign that key in the keyring. For Alice to sign Bob's key, she would do a command like this:

gpg --keyring /path/to/downloaded-keyring.gpg --sign-key "Bob" --local-user "Alice"

[That's a single command line, split in two for inclusion here.]

Remember, keep the keyring separate.

(Also, please don't sign keys of people you did not personally identify. If you don't take this process seriously, you are a weak link in the Web of Trust. If I see that you signed the key of someone who wasn't at the event, I won't sign -your- key, and I'll suggest that others don't, either.)

2. Once all the signatures have been added, send your copy of the keyring back to the signing party's organizer. This copy will now have all your signatures in it. Please return your signatures within one week.

3. The organizer will combine all the signatures together, and make the new, merged keyring available for download. You can download this file and then use

gpg --import /path/to/second/downloaded-keyring.gpg

To import all the keys with new signatures on them.


GnuPG Front-Ends:

There is now a modest selection of graphical, full-screen user-interface utilities to make GnuPG usage easier (e.g., for signing keys, exporting & importing keys from keyrings). I have no experience with them, but list them here for completeness:


Mutt Integration:

There are two ways to send gpg-encoded content: MIME and non-MIME. Some people, like me, don't like MIME e-mail and decline to send it, even to do GnuPG signing (RFC 3156 MIME mode). (Non-MIME is called "clearsigning".)

Note the two "macro" lines, below, which make Ctrl-P and Ctrl-S do signing inside the body of the message, with or without an "application/pgp" header.

The necessary, confusing GnuPG plumbing is in my .muttrc as follows (to do the clearsigning method):


source /usr/share/doc/mutt/examples/gpg.rc
# The contents of gpg.rc are given later in this document.

color body brightblack cyan "^gpg: Signature made.*"
color body brightblack green "^gpg: Good signature from.*"
color body brightblack yellow "^gpg: Can't check signature.*"
color body brightblack yellow "^gpg: WARNING: .*"
color body brightwhite red "^gpg: BAD signature from.*"

macro compose \CP "Fgpg --clearsign\ny"
macro compose \CS "Fgpg --clearsign\ny^T^Uapplication/pgp; \
format=text; x-action=sign\n"


The more-conventional approach would be to auto-sign all outbound mail, and do so using MIME. To do that, you would substitute the following for the preceding two macros (to do RFC 3156 MIME instead of clearsigning):

set pgp_default_version=gpg
set pgp_key_version=default
set pgp_receive_version=default
set pgp_send_version=default
set pgp_sign_micalg=pgp-sha1
set pgp_gpg=/usr/bin/gpg
set pgp_gpg_pubring=~/.gnupg/pubring.gpg
set pgp_gpg_secring=~/.gnupg/secring.gpg


Note that pubring.gpg and secring.gpg must exist (i.e., you must have a keypair), or you'll get errors.


The aforementioned gpg.rc plumbing (mostly to auto-process incoming GnuPG and pgp-signed mail) is as follows:

# -*-muttrc-*-
#
# Command formats for gpg.
#
# This version uses gpg-2comp from
# http://muppet.faveve.uni-stuttgart.de/~gero/gpg-2comp.tar.gz
#
# $Id: gpg.rc,v 1.7 2000/11/20 13:20:28 roessler Exp $
#
# %p The empty string when no passphrase is needed,
# the string "PGPPASSFD=0" if one is needed.
#
# This is mostly used in conditional % sequences.
#
# %f Most PGP commands operate on a single file or a file
# containing a message. %f expands to this file's name.
#
# %s When verifying signatures, there is another temporary file
# containing the detached signature. %s expands to this
# file's name.
#
# %a In "signing" contexts, this expands to the value of the
# configuration variable $pgp_sign_as. You probably need to
# use this within a conditional % sequence.
#
# %r In many contexts, mutt passes key IDs to pgp. %r expands to
# a list of key IDs.

# decode application/pgp
set pgp_decode_command="gpg %?p?--passphrase-fd 0? --no-verbose --batch \
--output - %f"

# verify a pgp/mime signature
set pgp_verify_command="gpg --no-verbose --batch --output - --verify %s %f"

# decrypt a pgp/mime attachment
set pgp_decrypt_command="gpg --passphrase-fd 0 --no-verbose --batch \
--output - %f"

# create a pgp/mime signed attachment
# set pgp_sign_command="gpg-2comp --no-verbose --batch --output - \
--passphrase-fd 0 --armor --detach-sign --textmode %?a?-u %a? %f"
set pgp_sign_command="gpg --no-verbose --batch --output - \
--passphrase-fd 0 --armor --detach-sign --textmode %?a?-u %a? %f"

# create a application/pgp signed (old-style) message
# set pgp_clearsign_command="gpg-2comp --no-verbose --batch --output - \
--passphrase-fd 0 --armor --textmode --clearsign %?a?-u %a? %f"
set pgp_clearsign_command="gpg --no-verbose --batch --output - \
--passphrase-fd 0 --armor --textmode --clearsign %?a?-u %a? %f"

# create a pgp/mime encrypted attachment
# set pgp_encrypt_only_command="pgpewrap gpg-2comp -v --batch --output - \
--encrypt --textmode --armor --always-trust -- -r %r -- %f"
set pgp_encrypt_only_command="pgpewrap gpg -v --batch --output - --encrypt \
--textmode --armor --always-trust -- -r %r -- %f"

# create a pgp/mime encrypted and signed attachment
# set pgp_encrypt_sign_command="pgpewrap gpg-2comp --passphrase-fd 0 -v \
--batch --output - --encrypt --sign %?a?-u %a? --armor --always-trust \
-- -r %r -- %f"
set pgp_encrypt_sign_command="pgpewrap gpg --passphrase-fd 0 -v --batch \
--textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust \
-- -r %r -- %f"

# import a key into the public key ring
set pgp_import_command="gpg --no-verbose --import -v %f"

# export a key from the public key ring
set pgp_export_command="gpg --no-verbose --export --armor %r"

# verify a key
set pgp_verify_key_command="gpg --no-verbose --batch --fingerprint \
--check-sigs %r"

# read in the public key ring
set pgp_list_pubring_command="gpg --no-verbose --batch --with-colons \
--list-keys %r"

# read in the secret key ring
set pgp_list_secring_command="gpg --no-verbose --batch --with-colons \
--list-secret-keys %r"

# receive key from keyserver:
#set pgp_getkeys_command="wrap.sh -g %r"
set pgp_getkeys_command=""

The above plumbing, included by reference in ~/.muttrc, isn't able to auto-process non-MIME-encoded mail (such as the type I send), so the following procmail recipe in ~/.procmailrc re-writes such arriving mail to be MIME-type, as it arrives. Make sure you put this recipe before others in your .procmailrc file.

:0
*!^Content-Type: (message/|multipart/|application/pgp)
{
:0 fBwD
*^-----BEGIN PGP MESSAGE-----
*^-----END PGP MESSAGE-----
| formail \
-i "Content-Type: application/pgp; format=text; x-action=encrypt"

:0 fBwD
*^-----BEGIN PGP SIGNED MESSAGE-----
*^-----BEGIN PGP SIGNATURE-----
*^-----END PGP SIGNATURE-----
| formail \
-i "Content-Type: application/pgp; format=text; x-action=sign"
}

Other Mailers (aside from Mutt):

Many security-cautious companies will require that outside users' inbound mail software support IMAP over SSL, and that whatever you use to send outbound mail support SMTP over SSL/TLS. It's therefore desirable to support those two cryptographic protocols, in addition to PGP/GnuPG. Except for mutt, I have not verified the mailers' ability to perform those other functions.

Results of my research will be (well, might be) updated here as I get them. (Please note that results may be incomplete, because many of these mailers have only vague crypto information on their Web sites, and many are moving targets.)

With some mail clients, you can use a modular approach: Pull down your mail using fetchmail-ssl, use shell scripts to apply GnuPG and feed the result to a non-integrated mailer, and/or use an external SMTP mail program that does SMTP-SSL/TLS -- as needed.


More information at:
http://www.bretschneidernet.de/tips/secmua.html.en
http://lists.gnupg.org/pipermail/gnupg-users/2002-October/015310.html
Suggestion: Mutt is your friend. Trust mutt.

Caveat: The above notes about various MUAs aim to cover information subject to change and difficult to chase down. If some of the comments are out of date or weren't even quite accurate when written, I won't be the least bit surprised.


Keyservers:

A keyserver is just a fancy, automated public keyring on a Web server, with a CGI interface to submit and revoke keys. Examples:

Keyserver doesn't provide assurance of trust; signatures on certs do.

Some keyservers in the past have failed to implement acceptance of revocation certificates. User beware.


Further Reading:

Mutt-i, GnuPG, & PGP HOWTO - http://tldp.org/HOWTO/Mutt-GnuPG-PGP-HOWTO.html
The GnuPG Handbook - http://www.gnupg.org/gph/en/manual.html
How PGP Works - http://www.pgpi.org/doc/pgpintro/
Keysigning Party Guide - http://www.w4kwh.org/privacy/keysign.html
"OpenPGP" RFC 2440 - ftp://ftp.isi.edu/in-notes/rfc2440.txt

Self-Certifying Filesystem, often used by security-conscious firms for outside-accessible file directories such as those containing mail spools and home directories.
http://www.fs.net/

Drew Streib does "Six degrees of Ted T'so" using GnuPG -
http://web.archive.org/web/20070406221220/http://dtype.org/keyanalyze/

Pine and GnuPG -
http://web.archive.org/web/20041102102835/http://www.linuxsecurity.com/feature_stories/feature_story-83.html
http://web.archive.org/web/20020223134914/http://www.helpdesk.umd.edu/unix/mail/pine/gpg/

Justin R. Miller's GnuPG HOWTO
http://codesorcery.net/old/mutt/mutt-gnupg-howto