March 04, 2009, 3:12 PM — I've only recently been motivated to encrypt a small portion of my email. Though I've been familiar with various encryption methods for a long time and PGP in particular, I found that I had to step back and do a lot of rehashing of what I know and don't fully understand about public/private key systems to come up with something that works.
GPG, for those of you thinking I meant to type PGP in the title of this week's post, stands for Gnu PG or GnuPG. GnuPG is the GNU project's complete and free implementation of the OpenPGP standard.
The basic idea behind GnuPG, and any public/private key system, is that you generate a pair of matched keys. One key decrypts what the other encrypts. They are referred to as public and private because one key (the public one) is to be shared with anyone you want to be able to send encrypted email to you that only you can read and the other (the private one), you keep to yourself so that no one else can decrypt email meant only for you.
Generating a Key Pair
You can generate a pair of keys using the command "gpg --gen-key". You will have to make a few decisions in this process, such as whether you want your keys to expire and how many bits your key should contain. The process will look more or less like this:
boson% gpg --gen-key gpg (GnuPG) 1.4.8; Copyright (C) 2007 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: WARNING: using insecure memory! gpg: please see http://www.gnupg.org/faq.html for more information Please select what kind of key you want: (1) DSA and Elgamal (default) (2) DSA (sign only) (5) RSA (sign only) Your selection? 1 DSA keypair will have 1024 bits. ELG-E keys may be between 1024 and 4096 bits long. What keysize do you want? (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) 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) " Real name: Sandra Henry-Stocker Email address: firstname.lastname@example.org Comment: bugfarm You selected this USER-ID: "Sandra Henry-Stocker (bugfarm) " Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O You need a Passphrase to protect your secret key.
The software will then go and create your keys, printing a lot of "++++>...+++" on your screen in the process. Notice that you are also required to enter a passphrase (twicce). You will have to type this phrase, in addition to having your private key installed, when you decrypt something that is encrypted for your eyes only. So, make it less than obvious, but don't make it impossibly difficult to type correctly.
Once your key pair has been created, you will have a .gnupg directory in your home directory. It will look like this:
-rw------- 1 bugfarm staff 9029 Feb 27 09:02 gpg.conf -rw------- 1 bugfarm staff 3566 Mar 4 14:16 pubring.gpg -rw------- 1 bugfarm staff 3566 Mar 4 14:16 pubring.gpg~ -rw------- 1 bugfarm staff 600 Mar 4 14:16 random_seed -rw------- 1 bugfarm staff 2651 Mar 4 14:16 secring.gpg -rw------- 1 bugfarm staff 1360 Mar 4 14:16 trustdb.gpg
None of these files should be sent to your intended correspondant. Instead, you will prepare a plain text version of your public key for sharing.
boson% gpg --armor --export email@example.com > bugfarm.pub gpg: WARNING: using insecure memory! gpg: please see http://www.gnupg.org/faq.html for more information
If you examine the public key file you have created, you will see that it starts with a BEGIN marker:
boson% cat bugfarm.pub -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.8 (SunOS) mQGiBEmu0uQRBACp6EAeo01UZ5UHjYoJvSKBr28FTD2ydaaKJg8MK5iQKFB/BP77 HhQQCmfM0boMDBBAD4P0sfA+LhuUtsF9PazZcsABX3ehUEBmDI18oSK5BeWKIZfC
It ends with a corresponding END marker:
OlgVeVwm45socrXEqGl+Wslx5854Q17GtKi/IMNLVB4j1jNhh4mepzs0XZMhqohJ BBgRAgAJBQJJrtLkAhsMAAoJEEpFm9USVTGwV2gAnjfoFlwRRE/UczOZPxDNo9jk sduWAJ0UCweQZ8TLoSdqwMD3facPrSkkoA== =Km04 -----END PGP PUBLIC KEY BLOCK-----
You will send this entire file, including the BEGIN and END markers, to your intended correspondant, who will then import your key like this:
fermion% gpg --import bugfarm.pub gpg: WARNING: using insecure memory! gpg: please see http://www.gnupg.org/faq.html for more information gpg: key 125531B0: public key "Sandra Henry-Stocker (bugfarm) " imported gpg: Total number processed: 1 gpg: imported: 1
Your correspondant will then encrypt messages for you like this:
fermion> gpg --recipient firstname.lastname@example.org --out testmsg.enc --encrypt testmsg gpg: WARNING: using insecure memory! gpg: please see http://www.gnupg.org/faq.html for more information gpg: E5D6FCEB: There is no assurance this key belongs to the named user pub 2048g/E5D6FCEB 2009-03-04 Sandra Henry-Stocker (bugfarm) Primary key fingerprint: B237 5EA6 37B4 C61D A16C 78A1 4A45 9BD5 1255 31B0 Subkey fingerprint: C6CF DA4B 3EFB CF7D D5DE F546 C0E2 6B00 E5D6 FCEB
It is NOT certain that the key belongs to the person named in the user ID. If you *really* know what you are doing, you may answer the next question with yes.
Use this key anyway? (y/N) y
When you receive the encrypted file, you can decrypt it with a similar command:
bash-2.03$ gpg --output testmsg --decrypt testmsg.enc gpg: WARNING: using insecure memory! gpg: please see http://www.gnupg.org/faq.html for more information You need a passphrase to unlock the secret key for user: "Sandra Henry-Stocker (bugfarm) " 2048-bit ELG-E key, ID E5D6FCEB, created 2009-03-04 (main key ID 125531B0) gpg: encrypted with 2048-bit ELG-E key, ID E5D6FCEB, created 2009-03-04 "Sandra Henry-Stocker (bugfarm) "
The testmsg file should then be available in plain text.
It might seem like a lot of trouble, but encrypting messages for a particular recipient is really not all that hard.