Protect your Documents with GPG
You may have already tried PGP/GPG public key encryption for documents or mail, but do you know what’s going on under the hood and what level of security you’re actually getting? We take an in-depth look at GnuPG encryption.
Pretty Good Privacy (PGP) provides cryptographic signing (to confirm identity) and encryption/decryption (to provide confidentiality) for documents according to the OpenPGP standard, which uses a combination of public key and conventional encryption to provide both security and speed. PGP itself, in terms of products available from the PGP Corporation, is not open source, but the OpenPGP protocol standard is non-proprietary. The main open source implementation of OpenPGP is GnuPG (GPG). In practice, the terms PGP and GPG are often used interchangeably; in this article, I’ll use GPG throughout.
Why Public Key Cryptography?
The basic idea of all cryptography is that an encryption process converts your original text from readable plain text into encrypted text, and then a decryption process converts it back into plain text. Only someone who knows the decryption process can decrypt the text; so, anyone who intercepts it is stuck.
To encrypt a text, you use an algorithm – a mathematical procedure of some sort that tells you what to do to the text – and a key. Using a different key with the same algorithm, or the same key with a different algorithm, on the same piece of plaintext will produce a different encrypted text. A really basic cipher that you might already have encountered is the Caesar cipher, whereby you shift every letter in the message by three. So A becomes D, B becomes E, and so on. As an algorithm, this becomes “shift every letter by X” with the key “3”. The key “4” would mean instead that you’d shift every letter by four.
This approach, obviously, is very easy to break and will not cut it as a modern encryption method. However, it does illustrate the key problem in cryptography: To decrypt your message, the recipient needs both the key and the algorithm. But, how do you get that information to them securely? You can’t encrypt it, because they don’t have any way to decrypt it yet (imagine sending a key inside a locked box). But, sending the information unencrypted makes it vulnerable to someone else who could intercept it and thereby get access to your encrypted messages.
The solution is public key cryptography, which uses one key (a public key) to encrypt a message, and another key (a private key) to decrypt it. Deducing the private key from the public key is computationally infeasible (see the “RSA and Computational Feasibility” box), so you can spread your public key around as much as you like without the risk that someone else will be able to read messages encrypted for you. You never need to share your private key with anyone else; as long as you keep it safe, you’re fine.
GPG: Two Methods for Best Results
The one problem with public key cryptography is that it’s slow. Symmetric key encryption (wherein the same key is used for encryption and decryption) is much faster, but it still has the key-sharing problem described previously. GPG solves this problem by using not one but two keys. When someone encrypting a message fires up GPG, it does the following:
- Compresses the message, making it more difficult to attack the cryptography by reducing the patterns seen in plain text.
- Creates a one-time-only symmetric session key: a random number generated from mouse movements and keystrokes.
- Encrypts the message with the session key.
- Uses the recipient’s public key to encrypt the session key (not the message itself).
The sender then sends the GPG-encrypted package, consisting of the message (encrypted with the session key) and the session key (encrypted with the recipient’s public key), to the recipient.
- At the other end, the process is reversed, and GPG does this:
- Uses the recipient’s private key to decrypt the session key.
- Uses the session key to decrypt the message.
- Uncompresses the message.
The recipient can now read the plain text. Note that although I’m talking about this in terms of two people sending each other a message, you can apply the same process to any piece of plain text, and the recipient and sender could be the same person.
The detailed operation of this requires some fairly heavy-duty modulo arithmetic, which is beyond the scope of this article. An example using much smaller numbers than are used in reality is available online if you want to delve into the mathematical detail.
Public Key Algorithms
A number of different algorithms are supported by GPG. To find out which algorithms your version of GPG supports, use the gpg --version command. The output from my own local version is shown in Listing 1.
Listing 1: Available Algorithms
01 Supported algorithms: 02 Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA 03 Cipher: 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH 04 Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224 05 Compression: Uncompressed, ZIP, ZLIB, BZIP2
The pubkey algorithm is used to generate the public/private keypair, which you will use over and over again. The cipher algorithm is used to generate the one-time-only symmetric key for each message. The hash checks the authenticity of the message, and compression does what you’d expect.
Note that although you can only choose your pubkey algorithm once (per key), and once you’ve generated it you’re stuck with that key type, you can use any of the cipher algorithms at any time with a given key. The key itself doesn’t care what sort of algorithm you use to encrypt the main body of the message. In fact, when you encrypt a message to send it to someone, part of their public key is a list of algorithms that they can handle. GPG will pick the recipient’s most preferred algorithm that it can handle at your end to use for encryption.
To check what your current preferences are, type gpg --edit-key user-id, then showpref at the Command> prompt (Figure 1).
To change the preferences, use the setpref command as described the GnuPG tutorial.
Before I look at pubkey and cipher algorithms, which are a bit more complicated, here is a quick rundown on hash and compression algorithms.
Compression is used partly to reduce the size of your file and the time taken to encrypt it and partly because it reduces the patterns seen in the plain text. Standard algorithms available on most Linux systems are zlib, bzip2, or zip. The differences between these aren’t particularly important for security; zlib is more compatible with older versions of PGP. Bzip2 is quite memory intensive, but it has a higher compression level and so will tend to produce smaller files.
Cryptographic hashes are used to guarantee data authenticity; you’ve probably run into the idea of a file’s “signature” when downloading software. A hash function generates a “fingerprint” from a file’s data. This fingerprint is unique, and it’s impossible to regenerate the file contents from the fingerprint alone. SHA1 is the usual default for GnuPG, but you should check the setup on your system to confirm your local default. SHA1 does have some known vulnerabilities (although still only theoretical and requiring a great deal of processing power). A competition to produce the SHA-3 algorithm is still ongoing, with a winner expected to be selected in 2012. For now, in practice, SHA1 is still a reasonable choice, with SHA-2 (which includes SHA-256 and SHA-512) as a better security alternative if you’re concerned about the vulnerabilities.
When thinking about algorithms and security, you should keep in mind two relevant measures: key length, which is the size measured in bits of the key itself, and cryptographic security, which is a measure of the fastest known attack on the algorithm, also measured in bits.
The cryptographic security measure cannot exceed key length (because trying every single available key of that length would eventually hit the one you’re using), but it’s often a bit shorter. Symmetric key algorithms tend to have a cryptographic security roughly similar to their length; asymmetric ones don’t, so you need a longer key to get the same security.
Public Key Algorithms
The pubkey algorithm options you’re likely to see are RSA, RSA-E, RSA-S, ELG-E, and DSA.
RSA is probably the most commonly used algorithm. It’s faster to verify than DSA but slower to sign; its main benefit is that it has key lengths of up to 4096 bits. RSA-768 was factored in 2010, and by 2007, the US National Institute of Standards and Technology (NIST) had already recommended phasing out 1024-bit keys by the end of 2010. Key lengths of 2048 bits should offer security for decades, and 2048-bit RSA is now the GPG default. RSA-S is for signing only, and RSA-E is for encryption only. Although this distinction is relevant to the details of the protocol, it’s not relevant at the user level for most people.
ELG-E is based on the Diffie-Hellman key agreement, invented in 1976. It’s also the predecessor of DSA. Various key lengths are available, but 2048 is the default and should be plenty. Before RSA, DSA+ELG-E was the standard key option (DSA is for signing only, and ELG-E is for encryption).
DSA is signature-only and won’t handle encryption (you need to pair it with ELG-E for encryption). It’s also limited to 1024-bit key length, which has a security of about 80 bits, so, for most people, it’s best to use RSA with a longer key. DSA2 will support larger keys; however, RSA has been widely supported for longer than DSA2, so it’s a better choice. RSA became the GnuPG default choice a couple of years ago for this reason – and to increase the key length to a default 2048 bits.
The cipher is the symmetric cipher used to encrypt the message whose key will be sent using the asymmetric (public) key. The standard choices fall into four groups: Triple DES, CAST5, Blow/Twofish, and the various AES options.
DES used to be standard many years ago, but it has only 56 bits, so it’s not at all secure these days. Triple DES is a straightforward way of increasing the key length by applying DES three times (with three independent keys). This gives a key length of 3×56=168, but because of a known possible attack, the security is, in practice, only 112 bits. If you want more security than that, you’ll need to use a different algorithm. Triple DES has no known security breaches, but it is computationally slow. It’s still the default algorithm in the OpenPGP standard, but not in GPG any more.
CAST5 (a.k.a. CAST-128) is a symmetric algorithm with a key size between 40 and 128 bits; if you’re going to use it, go for 128 bits. In most Linux installations, it’s the current GPG default. At present, there is no known way of breaking it short of brute force, so its security is also 128 bits.
Blowfish key length is between 32 bits and 448 bits, so you have a reasonable choice (32 bits is basically pretty useless). Unfortunately, it does need a fair bit of memory. Blowfish is similar in structure to CAST5. Twofish is a similar algorithm, with a longer block size and key length of up to 256 bits. Neither has been cryptographically broken, but security specialist Bruce Schneier recommends the use of Twofish over Blowfish.
AES stands for Advanced Encryption Standard and is now the NIST technique of choice to replace DES (formerly the most often used standard). AES uses a 128-bit key, AES192 uses a 198-bit key, and AES256 uses a 256-bit key. Each of these also uses a slightly more complicated algorithm than its smaller relatives. Which of these to choose is a little complicated, and cryptographers disagree. There are attacks on AES-256 and AES-192 that don’t exist on AES-128, but they’re still considered “secure” because of the computational cost of those attacks (i.e., it’s not in practice feasible to break them).
AES-128 is a bit faster than AES-256, so it might be a more practical option; AES-256 probably isn’t any weaker than AES-128. Keys of 128 bits are likely to be secure for somewhere between 10 and 50 years, depending on whom you ask. AES is now the official US government standard (128-bit for SECRET classified information, 192- or 256-bit for TOP SECRET).
You may also encounter IDEA, which is not included in the official GPG distribution because of a former patent restriction. It is another 128-bit key. Other ciphers are also available (e.g., the CAMELLIA ciphers used as the Japanese encryption standard) if you compile GPG from source.
Taking public key and cipher together, for a decent balance between security and speed, AES (128 or 256) or CAST5 with RSA 2048 is your best bet (AES+RSA is recommended by NASA). Certainly, if you want long-term security, you shouldn’t go with an asymmetric key length of less than 2048 bits or a symmetric key length of less than 128 bits. For more security over the much longer term, but at a slight performance cost, choose a longer RSA key length (e.g., 4096 bits).
Master Keys and Subkeys
I won’t cover the basic GPG key creation here because that’s amply covered elsewhere, but if you’re looking to maximize your security, you might want to consider setting up a master key with subkeys.
One setup is to have a master signing key and an encryption subkey. The signing key is used to sign files (to verify your identity) and also to help build your web of trust (by collecting signatures from people who have confirmed your identity). The encryption subkey is used to decrypt documents sent to you. You might want to manage these separately. For example, you might want a master signing key, which never expires, and an encryption subkey that you might want to expire at some point (e.g., if you ever think it has been broken).
To change your encryption subkey, just add a new subkey. Type gpg edit-key myuid to edit your key, type addkey to add a subkey to it, and choose your preferred algorithm, key size, and expiry options (Figure 2).
Once the key has been generated, you will need to type save to save it – not just quit. To expire a subkey, select it using key n (where n is its index in the list), then type expire to change its expiration date. If you don’t select a subkey, the expiration of your primary key will be changed.
To use the new key instead of your previous one, you’ll need to publish the updated public key. This is slightly inconvenient for people who wish to correspond with you because they’ll need to update their stored public key for you (after the encryption key has expired, they won’t be able to use it to encrypt), but the process is fairly straightforward. Because the new subkey is signed with your existing master key, there’s no need for extra signatures; everyone involved already trusts the master key. Don’t get rid of an expired key! You’ll still need it to decrypt old messages and documents.
To increase your security further, you can generate a subkey for signing as well as for encryption. The big advantage to this is that you can now store the subkeys on your main computer and use them for day-to-day signing and encryption, and you can keep the master key somewhere else safe. Do make sure it really is safe, and also backed up, and that the backup is safe. You’ll still need the master key to sign someone else’s key, to create new subkeys, and to revoke subkeys if needed. Now, if your main computer is stolen or hacked, your master key is safe. Note that even if someone stole your master key, they’d still need to break your password to use it; however, breaking your password is probably easier than breaking the key algorithms.
Once you’ve created your new subkeys, copy ~/.gnupg to your safe place(s). Then, on your master computer, you need to remove the private master key, which is slightly complicated. To begin, export all your secret keys, as in Listing 2.
Listing 2: Export Your Subkeys
01 $ gpg --list-secret-keys 02 /home/me/.gnupg/secring.gpg 03 ------------------------------- 04 sec 1024D/01234567 2000-01-01 05 uid My Name <firstname.lastname@example.org> 06 ssb 1024g/11223344 2011-01-01 07 ssb 2048R/98989898 2012-01-01 08 09 $ gpg --export-secret-subkey 11223344 > subkey1 10 $ gpg --export-secret-subkey 98989898 > subkey2
Export each subkey (that you want to keep on your main machine) using its ID to a separate file, as shown in the listing. Then, export the public key with gpg --export 01234567 > pubkeys, where 01234567 is the key ID of your master key.
Next, remove the master key (once again, make sure you have it safely backed up) and import your secret keys back again, as in Listing 3.
Listing 3: Remove and Re-Import Master Key
01 $ gpg --delete-secret-key 01234567 02 $ gpg --import pubkeys subkey1 subkey2
Type gpg -K, and the sec line should show sec# instead, which means that the secret key isn’t really there.
When you want to use the master key again, just mount your USB key (or otherwise access wherever you’ve stored it) and use gpg --home=/where/my/key/lives -K.
To upload your new keys to a public keyserver, use the following command:
gpg --send-key --keyserver my.preferred.keyserver MASTERKEYID
Finally, one more hint could be useful when using subkeys. The process above generates a subkey and signs it with the master key, proving that it belongs to the master key. However, the subkey doesn’t sign the master key to show that it is owned by the public key. In theory, an attacker could take a signature subkey and attach it to his own key, meaning that a signature could be verified both by your own master key, and by the attacker’s master key. An attacker can’t issue any signatures from that key – only claim an existing one. To detect the problem, ask the attacker to issue a new signature on new data – the attacker can’t do it, thus demonstrating that he or she is not the real person.
To prevent this problem from occurring in the first place, enter cross-certify when editing the key with gpg --edit-key. Note that you will need access to the master key to do this. The key is now cross-certified and all is well. New subkeys should automatically be cross-certified, so you should only need to do this with older subkeys.
To keep your documents and mail secure, GPG is a safe bet. But, GPG is at its most useful when it’s working with other apps. Mail clients are the most covered, but you can also get GPG plugins for browsers and for Jabber clients and servers. See the “Implementing GPG with Other Apps” box.
Juliet Kemp is a freelancer writer who likes her email and documents secure.