General Usage

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

Start with 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: 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.

Checking Keys

To see what keys you have stored on your "keyring" (which usually lives in ~/.gnupg/pubring.gpg and ~/.gpgpg/secring.gpg) do:

gpg --list-keys

Or to get the fingerprints:

gpg --fingerprint

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.

The PGP handler code in a file called .mutt_gpg_config
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.

Include this in .muttrc
source ~/.mutt_gpg_config

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.

  1. 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.

  2. I installed it with:

    rpm -ivh pgp*
  3. Typing this should tell you if the install went ok and what version:

    pgp -h
  4. 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.

  1. 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 <>
        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.

  1. 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.

  1. 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.
  2. 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
Command Reference
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:
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


 -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


 -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


 -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 <>.