I started using GnuPG extensively in February 2003, and since March 2003 I’ve been signing almost every piece of email that I send out. One of the reasons it took me so long to get started using cryptography is because I had a hard time finding good explanations of how to do common things, like encrypt files or verify detached signatures on tarballs. So I decided that once I got comfortable using GnuPG, I would start a collection of scribblings explaining how to do things, as I learned how to do them. I’m now going to start making good on that decision.
I’m not going to explain the basic concepts, so you should already have read the GNU Privacy Handbook. Alternately, you can read up on Public Key Cryptography, Symmetric Cryptography and Hash Functions on WikiPedia. Phil Zimmerman‘s Why do you need PGP? is also a very interesting read, and provides historical perspective.
(NB: In the examples below, WordPress has compressed the double-dashes (- -) at the beginning of long options into a — ; If you’re playing along at home, copy the short forms to try out the examples).
The most common reason one might want to use crypto is for encrypting mail. However, that topic depends so much on the mail client and operating system you’re using; I limit myself to Unix-ish machines (Linux, Solaris, and OpenBSD) and a single MUA (mutt), so I’m not really going to try to cover that.
There are many good overviews of encrypting mail using GnuPG on the web, most of them tied to specific mail clients. See the mutt GnuPG HOWTO for a good overview of how to di it with mutt, for example, or Enigmail for integrating GnuPG with Thunderbird. Google is bound to have something interesting, too.
Something I find myself doing quite often is encrypting my files, to keep them confidential. There are two ways to do this: Encrypt the file to a public key, or use symmetric encryption. Using symmetric encryption means that anyone who knows the passphrase can decrypt the file, which is useful in many circumstances. Encrypting to a public key means that the corresponding private is required to decrypt the file.
When you encrypt a file, the original filename is stored within the encrypted file.
When using symmetric encryption, all of the security is in the passphrase you choose, since there is no private key component, so be sure to choose a good passphrase. Use –the --symmetric option to gpg:
$ gpg --symmetric FILE
This will produce a new file called FILE.asc (assuming that FILE is the original). To control the output filename, use the --output option:
$ gpg --symmetric --output NEWFILE FILE
This new file is in a binary format, however:
$ file NEWFILE NEWFILE: data
Originally, PGP was designed primarily for use with email, and email systems are designed to be used with ASCII test, so a plain ASCII format was added. To make the output file be in a text format, you can use this ASCII-armored format, which is enabled with the --armor option:
$ gpg --symmetric --output NEWFILE --armor FILE $ file NEWFILE NEWFILE: PGP armored data message
Armoring your encrypted files is not required, since gpg doesn’t care, and can decrypt either format, but if you are sending these files around, the plain text is generally easier to deal with than the data version.
Typing --symmetric --armor gets to be a pain in the wrists after not too long, so there are shortened forms of these commands: -c and -a. --output can be shorted to -o.
$ gpg -ca -o NEWFILE FILE
The --output option accepts - as a value, which indicated standard output, so that gpg can be used in pipelines:
$ gpg -ca --output - FILE | mail -s "Encrypted FILE" me@localhost
In place of a filename, you can use - to indicate standard input:
$ grep sshd /var/log/authlog | gpg -ca -o logins.txt -
In each of these cases, there is no signature on the encrypted file. This means that if someone decrypts the file, changes it, and re-encrypts it with the same passphrase, you might not be able to tell. If you are using symmetric encryption to share files with several people, this might be an issue. Luckily, signing the files as you are encrypting them is straightforward: Simply add the --sign option (abbreviated as -s):
$ gpg -sca FILE
gpg will sign the file first, and then encrypt it, so that the signature is wrapped in the encrypted file (this makes it harder to tamper with the signature). When this file is decrypted, gpg will check the validity of the signature, and display the results.
Encrypting To A Public Key
Instead of symmetric encryption, you can encrypt to a public key. This has a few advantages, the most important of which is that the corresponding private key is required to decrypt the files.
To specify the key to which the file should be encrypted, use the --recipient (-r) flag:
$ gpg --sign --encrypt --armor --recipient 0xb56165aa --output NEWFILE FILE $ gpg -sea -r 0xb56165aa -o NEWFILE FILE
If a user is not specified, gpg will prompt you for a key ID to use for them encryption:
$ gpg -ea nav-commenters.gif You did not specify a user ID. (you may use "-r") Enter the user ID. End with an empty line:
The file can be encrypted to multiple keys, specified by supplying the --recipient multiple times. However, gpg will devulge the keys to which a file has been encrypted quite easily:
$ gpg --list-packets NEWFILE :pubkey enc packet: version 3, algo 16, keyid 81679E80D1D94757 data: [2048 bits] data: [2048 bits] :pubkey enc packet: version 3, algo 16, keyid D4B533BB179C3425 data: [2047 bits] data: [2047 bits] :pubkey enc packet: version 3, algo 16, keyid ABFA8B4CE27736E2 data: [1022 bits] data: [1021 bits] You need a passphrase to unlock the secret key for user: "Darren Chamberlain" 1024-bit ELG-E key, ID E27736E2, created 2003-02-22 (main key ID B56165AA) Enter passphrase:
The --list-packets command displays the individual elements in the encrypted file. This is useful for showing the structure of the file, without necessarily decrypting it (it also works for signed files and detached signatures). As you can see above, the keys to which the file was encrypted are displayed, as well as the encryption algorithm used to encrypt the file.
Decrypting an encrypted file is as simple as invoking gpg on it:
$ gpg NEWFILE
You will be prompted for the passphrase at this point. If the file was encrypted to a public key that you own, the prompt will say so:
$ gpg NEWFILE You need a passphrase to unlock the secret key for user: "Darren Chamberlain" 1024-bit ELG-E key, ID E27736E2, created 2003-02-22 (main key ID B56165AA) Enter passphrase:
Otherwise, if the data was encrypted symmetrically, you will get a generic passphrase prompt:
$ gpg NEWFILE gpg: CAST5 encrypted data Enter passphrase:
If the message was signed, the signature will be checked after the file is decrypted, and the results will be displayed.
A detached signature is a file that contains a signed hash of another file. When creating a detached signature, gpg creates a checksum of the file, using the SHA1 message digest algorithm by default, and then encrypts that checksum with the user’s private key. When verifying this signature, gpg will generate a new checksum, using the same algorithm, and then compare this newly generated checksum with the checksum retrieved from the detached signature. If the two match, then the file has not been tampered since the original signature was made.
Many people distribute detached signatures with software tarballs. These signatures can be used to verify that the tarball you have downloaded is the same tarball that the author uploaded. If the FTP server containing the software had been compromised, and the tarball replaced with a malicious program, the signatures would not verify, and you would know not to install the faulty program. If the attacker replaced both the tarball and the signature file, the signature would not be made with the original author’s key, which would alert you to the fact that something weird was going on.
Verifying Detached Signatures
To verify a detached signature, use the --verify command:
$ gpg --verify ssh-hostfpr.asc ssh-hostfpr gpg: Signature made Thu 01 Jul 2004 01:48:35 PM EDT using DSA key ID B56165AA gpg: Good signature from "Darren Chamberlain" gpg: aka "Darren Chamberlain <email@example.com>" gpg: aka "Darren Chamberlain <firstname.lastname@example.org>" gpg: aka "Darren Chamberlain <email@example.com>" gpg: aka "Darren Chamberlain <DARREN@cpan.org>" gpg: aka "Darren Chamberlain <firstname.lastname@example.org>"
If the signature does not verify, the signed file has changed:
$ echo >> ssh-hostfpr $ gpg --verify ssh-hostfpr.asc ssh-hostfpr gpg: Signature made Thu 01 Jul 2004 01:48:35 PM EDT using DSA key ID B56165AA gpg: BAD signature from "Darren Chamberlain"
If you use something other than a detached signature, you’ll get a different error:
$ gpg --verify ssh-hostfpr.md5 ssh-hostfpr gpg: no valid OpenPGP data found. gpg: the signature could not be verified. Please remember that the signature file (.sig or .asc) should be the first file given on the command line.
Creating Detached Signatures
To create a detached signature, use the --detach-sign (-b) option:
$ gpg -b FILE
The signature will be in FILE.asc, unless you specify the --output option:
$ gpg -b --output FILE.SIG FILE
@@TODO: Give examples: mutt, apache, snownews, CHECKSUMS (cpan)
Inline Signatures on Documents
@@TODO Examples, Shortcomings
@@@TODO Checking fingerprints, Keyid collisions
Getting People’s Keys
@@TODO: keyserver; X-Pgp-Request-Url; <link rel=”meta” />; <wot:pubkeyAddress />; AUTRIJUS’s PUBKEY file
on CPAN; Apache KEYS file
@@TODO: subkeys.pgp.net, biglumber
@@TODO: Document signatures signing FOAF files