PGP, or "Pretty Good Privacy" is the classic piece of software which applies strong encryption to anything that needs it with a particular emphasis on email. Don’t let the name fool you, the privacy is more than pretty good, it is superlative. There were patent and export regulation issues surrounding the original PGP, so the good folks at GNU went ahead and resynthesized the functionality from scratch and created GPG as a drop in clone unencumbered by any legal nonsense. GPG stands for "Gnu Privacy Guard". The GPG website is here.
For information on using PGP/GPG for symmetric file encryption not necessarily involved in email, see my crypto notes.
Generating A Key Pair
gpg --gen-key. I mostly choose the defaults of "RSA and
RSA" and 2048 bits. I did choose an expiration date since this key is
going to be a work key, it doesn’t need to follow me around for the
rest of my life. Also in the event of a catastrophic compromise, an
attacker can’t spoof me for more than a couple of years. A note about
the key wants to store about you. If you tell it your real name and
email address, and if you submit the key to a key server, then you
will never be able to get that off the internet. Never. So give this
some serious thought. There’s no crime in lying to the spammers that
harvest email addresses from key servers (according to the MIT
keyserver FAQ) as long as you have another good plan for letting the
good people know you are you.
For work purposes, I generated a key with a 2 year (roughly - I made it end at New Year’s for easy planning) validity using a job title and a mail role alias set up by my employer (for example: email@example.com). That way if I change jobs, I can give this key to the successor and life can go on without interruption for the users.
You need to think of a pass phrase and it really wants you to use a number and special characters. After that, you need to generate some entropy. Sometimes, it seems especially on an SSH connection, this can be quite tricky. I opened up another screen session and did:
find / 2>/dev/null > /dev/null
After waiting a minute or so, it worked.
To see what keys you have stored on your "keyring" (which usually
Or to get the fingerprints:
The fingerprints are a short form of the public key that you can use to verify a key "by hand". I think it’s some kind of hash.
Dealing With Keys
Often someone sends you a signed message and you don’t have their PGP/GPG key. In fact, you’re more sure from the message context that they are the right person than from the signature. Maybe, they put their key on a key server. Check here…
If you put your key there, note that it can never go away and you can never pull out personal information.
Mutt and GPG
It’s a good idea to create a special file just for Mutt configuration relating to PGP/GPG. Here’s the one that I use.
set pgp_decode_command="/usr/bin/gpg %?p?--passphrase-fd 0? --no-verbose --batch --output - %f" set pgp_verify_command="/usr/bin/gpg --no-verbose --batch --output - --verify %s %f" set pgp_decrypt_command="/usr/bin/gpg --passphrase-fd 0 --no-verbose --batch --output - %f" set pgp_sign_command="/usr/bin/gpg --no-verbose --batch --output - --passphrase-fd 0 --armor --detach-sign --textmode %?a?-u %a? %f" set pgp_clearsign_command="/usr/bin/gpg --no-verbose --batch --output - --passphrase-fd 0 --armor --textmode --clearsign %?a?-u %a? %f" set pgp_encrypt_only_command="pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --always-trust --encrypt-to 0xYOURKEYIDHERE -- -r %r -- %f" set pgp_encrypt_sign_command="pgpewrap gpg --passphrase-fd 0 --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --always-trust --encrypt-to 0xYOURKEYIDHERE -- -r %r -- %f" set pgp_import_command="/usr/bin/gpg --no-verbose --import -v %f" set pgp_export_command="/usr/bin/gpg --no-verbose --export --armor %r" set pgp_verify_key_command="/usr/bin/gpg --no-verbose --batch --fingerprint --check-sigs %r" set pgp_list_pubring_command="/usr/bin/gpg --no-verbose --batch --with-colons --list-keys %r" set pgp_list_secring_command="/usr/bin/gpg --no-verbose --batch --with-colons --list-secret-keys %r" set pgp_autosign=yes set pgp_sign_as=0xYOURKEYIDHERE set pgp_replyencrypt=yes set pgp_timeout=1800 set pgp_good_sign="^gpg: Good signature from" # Don't know if this is needed but leaving it here for reference: #set pgp_strict_enc # use Q-P encoding when needed for PGP
Of course you need to get this activated for the Mutt session you’re running.
Original Notes On How I First Authenticated PGP
The first thing you have to do is to get pgp. As of 1999 there seems to be a version 5.00 and a bunch of version 2.6’s. There is much confusion in general about which version does what due to legal nonsense pertaining to the USofA. I got my version of pgp in Europe and IMPORTED it into the USA. I feel perfectly ok with that. I’m using 2.6.3i right now.
Where you get your pgp is the next issue. This is a sensitive thing really since if some imposter/bad guy was going to do anything nefarious with any program, this would be it. And cryptography is a lot of fun as an academic exercise anyway, so here are the steps I took to have a clean copy.
I got my copy in rpm format from a Linux CD that I got out of a German Linux book. This does in no way guarantee that you have a "clean" copy of it.
I installed it with:
rpm -ivh pgp*
Typing this should tell you if the install went ok and what version:
Now, your copy could be totally bogus and planted by an imposter - how can you tell? In the distribution, there is a set of keys that I found at:
This set of keys has all the pgp bigshots on it like Phil Zimmerman himself, pgp’s main and original author.
Here’s the really evil part: if you were a bad guy, you would, of course, substitute a bogus public key for Phil so that you could keep up the appearance that everything was ok. Since you probably don’t know Phil personally, the keys that are listed are rather arbitrary. What needs to happen is that you need to link that key with reality in some way. Phil’s a busy guy and discussing the specifics of your pgp package is probably out of the question (and with driver’s licenses so easy to forge, how would you know him if you met him anyway?). The basis for my trust started with Simson Garfinkel and book publisher, O’Reilly. On page 262, Simson lists explicitly for this very reason, Phil’s public key fingerprint which appears to be:
pub 1024/C7A966DD 1993/05/21 Philip R. Zimmermann <firstname.lastname@example.org> Key fingerprint = 9E 94 45 13 39 83 5F 70 7B E7 D8 ED C4 BE 5A A6
Don’t take my word for it, hop on down to the book store and check it out yourself - that’s what a properly paranoid person would do.
Assuming that Phil Zimmerman is a real guy who is promoting proletariat privacy and not some construct of the NSA, we can assume that a book called PGP at Barnes&Noble would have caught his eye and he’d raise hell if his fingerprint was wrong.
So now you must check to make sure that your copy of pgp digests Phil’s key into what the printed universal version dictates. To do this, you have to pull all of the keys into a "keyring" (this is step 1):
$ pgp -ka /usr/doc/pgp-2.6.3i-1/keys.asc ~/temp.pgp
After creating this keyring in your home directory (or wherever you like):
$ pgp -kvc Zimmerman ~/temp.pgp
will give you an output of the key associated with Phil.
First off, that key should match the one in the online documentation as well as the printed book. Use this command:
grep -A 2 "Philip R. Zimmermann <" /usr/doc/pgp-2.6.3i-1/pgpdoc2.txt6.
Ok, off on another oddessy since Phil didn’t really have anything to do with the rpm. The above checks are pretty rough. Let’s get the source:
rpm -ivh pgp-2.6.3i.src.rpm cd /usr/src/redhat/SOURCES/ tar -xvzf pgp263is.tar.gz
Gnu Privacy Guard (GPG) Help commands gpg (GnuPG) 1.0.0 Copyright (C) 1999 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. Supported algorithms: Cipher: 3DES, CAST5, BLOWFISH, TWOFISH Pubkey: ELG-E, DSA, ELG Hash: MD5, SHA1, RIPEMD160 Syntax: gpg [options] [files] sign, check, encrypt or decrypt default operation depends on the input data Commands: -s, --sign [file] make a signature --clearsign [file] make a clear text signature -b, --detach-sign make a detached signature -e, --encrypt encrypt data -c, --symmetric encryption only with symmetric cipher --store store only -d, --decrypt decrypt data (default) --verify verify a signature --list-keys list keys --list-sigs list keys and signatures --check-sigs check key signatures --fingerprint list keys and fingerprints --list-secret-keys list secret keys --gen-key generate a new key pair --delete-key remove key from the public keyring --sign-key sign a key --lsign-key sign a key locally --edit-key sign or edit a key --gen-revoke generate a revocation certificate --export export keys --send-keys export keys to a key server --recv-keys import keys from a key server --import import/merge keys --list-packets list only the sequence of packets --export-ownertrust export the ownertrust values --import-ownertrust import ownertrust values --update-trustdb update the trust database --check-trustdb [NAMES] check the trust database --fix-trustdb fix a corrupted trust database --dearmor De-Armor a file or stdin --enarmor En-Armor a file or stdin --print-md algo [files] print message digests Options: -a, --armor create ascii armored output -r, --recipient NAME encrypt for NAME --default-recipient NAME use NAME as default recipient --default-recipient-self use the default key as default recipient -u, --local-user use this user-id to sign or decrypt -z N set compress level N (0 disables) --textmode use canonical text mode -o, --output use as output file -v, --verbose verbose -q, --quiet be somewhat more quiet --no-tty don't use the terminal at all --force-v3-sigs force v3 signatures --force-mdc always use a MDC for encryption -n, --dry-run do not make any changes --batch batch mode: never ask --yes assume yes on most questions --no assume no on most questions --keyring add this keyring to the list of keyrings --secret-keyring add this secret keyring to the list --default-key NAME use NAME as default secret key --keyserver HOST use this keyserver to lookup keys --charset NAME set terminal charset to NAME --options read options from file --debug set debugging flags --debug-all enable full debugging --status-fd FD write status info to this FD --no-comment do not write comment packets --completes-needed (default is 1) --marginals-needed (default is 3) --load-extension FILE load extension module FILE --rfc1991 emulate the mode described in RFC1991 --openpgp set all packet, cipher and digest options to OpenPGP behavior --s2k-mode N use passphrase mode N --s2k-digest-algo NAME use message digest algorithm NAME for passphrases --s2k-cipher-algo NAME use cipher algorithm NAME for passphrases --cipher-algo NAME use cipher algorithm NAME --digest-algo NAME use message digest algorithm NAME --compress-algo N use compress algorithm N --throw-keyid throw keyid field of encrypted packets -N, --notation-data NAME=VALUE use this notation data Examples: -se -r Bob [file] sign and encrypt for user Bob --clearsign [file] make a clear text signature --detach-sign [file] make a detached signature --list-keys [names] show keys --fingerprint [names] show fingerprints Please report bugs to <email@example.com>.