Wednesday, August 5, 2009

Basics of using GPG for signing, encrypting, exchanging, etc.

I recently had need to interchange some information that needed to be signed and encrypted. My colleague was using GPG, so I had to get it set up.

GPG is a good, free, secure package with a very basic command line interface for working with keys, encrypting, and decrypting things. It is basically an open source version of PGP (kind of a defacto standard for cryptography packages).

The basic steps for using it are shown below.

Install GPG

Install GPG by downloading (the Windows version, in my case) the command line interface. (ftp://ftp.gnupg.org/gcrypt/binary/gnupg-w32cli-1.4.9.exe for me). I plopped mine in C:/apps/GnuPG.

Create a Key

Create a key: 'gpg --gen-key.' It asks a bunch of questions and I ended up with a "DSA and Elgamal" key of 2048 bits, non-expiring, with a UID of "Richard Mills (GPG Key) ."

Export a copy of the key that you can share: 'gpg --export -a > gpgkey.pub.export.txt'

This has an ascii format similar to

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.9 (MingW32)

mQGiBEp5hgoRBADnOunnwGSicNhPXwZfrO+KY5KqM9eEYBzs8xsF6XnKbuHwmewb
rJuPrUkQntwYKCVYJxNiITe+U/i4ovHcdX5bMl6u57N34uUZ2EQPxuSVPodZsOEt
....
eYYKAhsMAAoJEJh6yxSN8tuIgWQAoLuI04SOOxJ6hjGFTsE5wqNBlqkJAKC4A2qC
uC2gEiXUd7Xu0Alquau49w==
=DYre
-----END PGP PUBLIC KEY BLOCK-----

Encrypt Something

To encrypt something, you need the public key of the "Recipient" who you want to be able to decrypt the file. For the simple case, you can encrypt something for yourself that you can decrypt later. It will ask a few questions along the way that you need to answer.

$ gpg --encrypt foo.txt
You did not specify a user ID. (you may use "-r")

Current recipients:

Enter the user ID. End with an empty line: rmills

Current recipients:
2048g/83F23E72 2009-08-05 "Richard Mills (GPG Key) "

Enter the user ID. End with an empty line:

This will result in a file 'foo.txt.gpg' that is the encrypted version of your file. Note that the "Recipient" means the person to whom you want to send the file (could be yourself). You must have this person's public key in your key ring to encrypt it. The only person who will be able to decrypt it will be the person with the matching private key.

Decrypt Something

Decrypt the file (assuming you were the recipient):

$ gpg --decrypt foo.txt.gpg > foo.txt.new

You need a passphrase to unlock the secret key for
user: "Richard Mills (GPG Key) "
2048-bit ELG-E key, ID 83F23E72, created 2009-08-05 (main key ID 8DF2DB88)

gpg: encrypted with 2048-bit ELG-E key, ID 83F23E72, created 2009-08-05
"Richard Mills (GPG Key) "

NOTE that you need to type in the passphrase for the private key in order for the file to be decrypted.

Sign Something

Signing something is useful to ensure the integrity of it during transport. Signing involves applying your private key to something such that your public key can be used to verify that the data has not been modified. In many cases you may want to 'clear text sign' the piece of data such that it is still legible without having to be decrypted.

gpg -s foo.txt

This will create 'foo.txt.gpg' which is a new binary (obscured) version of your data. It will need to be decrypted with 'gpg -d' before it can be read. Alternately, you can use "cleartext" signing that encodes everything in ASCII such that it is readable without actually decrypting it.

gpg --clearsign foo.txt

This produces a file 'foo.txt.asc' which is readable and looks something like this:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)

iEYEARECAAYFAkp5tk4ACgkQmHrLFI3y24iu8QCePQ/ic5S71V9BkPtUB6OiT1cx
JeQAnRcvjZiaMnTEQJ8KgdZ8DKpFbzSN
=kXkG
-----END PGP SIGNATURE-----

This file can be transported through normal ASCII transport mechanisms (e.g., email). It can be verified (see below) in the same was as if it was obscurred.

Verify Signature and Retrieve Something

Verifying a signature is important to ensure that a piece of data has not been modified since it was signed. To do this, use 'gpg --verify file.signed.' GPG will use your local public key ring to verify any/all people who's keys were used to sign the piece of data. Note that in some cases, multiple people may have signed the data along it's route to you. To properly trust the data, you need to actually trust ALL the people back to the origin.

To actually GET the data that has been signed, you need to decrypt it.

$ gpg -d foo.txt.gpg > foo.verifysig.txt
gpg: Signature made 08/05/09 12:43:05 using DSA key ID 8DF2DB88
gpg: Good signature from "Richard Mills (GPG Key) "

The file "foo.verifysig.txt" will now contain the data you actually want.

Exchange Public Keys with Someone

Generally, you want to be able to pass your public key around to your colleagues such that they can use it to verify signed messages from you as well as encrypt data that can be sent to you. It is important that public keys are maintained intact such that someone cannot masquerade as someone else. More on that below.

The easiest way to exchange keys is to simply email them. Alternately, you can publish them on your web page, or really put them anywhere that people can find them. Use 'gpg --export -a' to generate a ASCII format key (as shown above), then email it to your buddy. He should do the same for you.

Once you get a key, you need to import it into your keyring.

Typing 'gpg --list-keys' will show you all the keys you have in your public key ring (including yours). Also, 'gpg --fingerprint' will show you the finger prints of those keys such that you can verify they match what you expect (e.g., if the other person sent you a finger print to verify it).

Proper Handling of Keys

Generally, you can send your public key to whomever you want (hence the name "public"), but it is critically important to protect your private key and the matching passphrase. If someone were to steal your private key and the passphrase, they would be able to decrypt anything intended for your eyes only was well as masquerade as you when signing messages.

Although you can send public keys to anyone, it is useful for them to ensure that the public key remains intact so they can verify your signature and also encrypt data to send to you. This means the onus comes on the recipient to protect any public keys that are received. This can be done by comparing fingerprints of keys with the keys themselves. Fingerprints are sufficiently small such that you can easily compare them even by reading them over the phone to each other. Once you are confident that a public key is authentic, you can sign it using gpg and assign it a particular value of trust. I'll save that discussion for another day.