Unix Insider –
Networked computing is a double-edged sword. Connectivity makes transparent sharing of data through e-mail, Web sites, and ftp archives possible, but it also invites unwanted access to your data. Bytes sent over a network are about as private or secure as Post-it notes posted outside your cubicle wall. You're open to data loss through copying, incorrect or inconsistent messages coming from someone impersonating you, or the exposure of sensitive information.
Last month, we looked at the secure shell (ssh), a session-level encryption system that lets you move from system to system over an unsecure network safely. SSH is suited for synchronous work, such as remote logins or X sessions.
Our budding e-mail culture, however, demands protection for asynchronous, file-based communication as well. To extend the scope of the data protection problem, you need to ensure the privacy and integrity of any number of files, knowing the identity of each file's creator and the validity of its contents. This month, we'll explore Pretty Good Privacy (PGP), Phil Zimmermann's publicly available, file-oriented encryption system. PGP can encrypt your mail and other files and attach digital signatures to files, whether they are encrypted or not.
Starting with some motivations for using PGP in the first place, we'll cover the mechanics of encrypting and decrypting files. We'll tell you how and where to get PGP, and why you need to treat it like radioactive material (seriously!). Key management, trust, and key validity form the core of a socio-political discussion, and we'll point out some safe and unsafe key exchange and protection practices. Finally, we'll tie everything together with a discussion of generating digital signatures and using them to verify data integrity and sender identity.
Say what? The need for authenticity
Don't dismiss data security as a problem for the boundary between inside and outside networks, or one that is covered by company policies regarding personal use of resources. While data privacy is nice for protecting e-mail sent to your significant other or sister in New York, it can also be a requirement for internal networks. Consider some of these scenarios:
- A contractor whose engagement has expired wants to retain an account on your machine for cheap Internet access. He forges e-mail from your manager asking you to leave his login active for another 90 days. Do you accept requests like this by fiat, or do you have a verification process?
- For an April Fool's Day prank, some of your co-workers hand-craft an official looking e-mail from the head of human resources outlining the new company dress code: wing-tip shoes and shorts, especially on Hawaiian Shirt Gonzo Fridays. Various executives go ballistic -- aiming at you -- because you had assured them that mail to the all-company alias went through an auditing script.
- You sense that someone has broken into one of your gateway machines, but you can't determine exactly what has changed. You consult your list of configuration files, but it matches the size, date, and owner information found on the system. Either you're paranoid, or the intruder modified the system and your checklist to hide the damage.
- A chunk of e-mail containing bonus information gets copied off of
the wire, revealing salary information to anyone who can divide by the
appropriate fraction. Using ssh prevents disclosure while
reading your mail, but how do you protect the contents while
they are in
<font face="Courier">sendmail</font>'s grip?
The solution to these problems, and others like them, is PGP. Command-line driven, PGP can be embedded in scripts or used as a standalone encryption tool. PGP's major attraction is that it uses public key cryptography, allowing you to exchange encrypted files without having to swap private, or secret key information with the other party.
You could solve the bonus e-mail problem, for example, by encrypting the file using
<font face="Courier">crypt</font>, but each recipient of the message would have to be given the key to decrypt it. This symmetric, or private key encryption, requires that both parties have the same key. It's fast, but it's also a mess to manage. If you want to send private mail to each of three people, and want to ensure the privacy of mail to each one, you need three secret keys. Extend the problem to the more likely case where all four of you want to exchange secret mail, and you need six keys to cover all combinations of sender and receiver. This combinatorial gem grows exponentially, making it nearly impossible to handle for anything outside of a small group.
Public key cryptography solves the problem by breaking the key up into a public and private portion. You keep the private portion secret, like a password, but freely distribute the public portion. The magic behind public key cryptography is that two parties can derive a shared key between them without ever exchanging secret (private key) information.
Returning to our example of exchanging secret mail, you'd only need four keys to exchange mail amongst four people -- each person needs a copy of every other's public key. Adding a new person to the circle requires distributing just one new public key.
Public key cryptography relies on such mathematical coolness as exponentiation, large numbers, prime numbers, and the commutative property of multiplication. Some of that is second-grade math, while most of it is twenty-year-old work done by Whitfield Diffie and Marty Hellman (the Diffie-Hellman key exchange) and Ron Rivest, Adi Shamir, and Len Adelman (RSA encryption). For now, all you need to know is that exchanging public keys with someone lets you exchange strongly encrypted data. RSA keys are typically 512, 768, or 1,024 bits long: the longer the key, the stronger the encryption. With 1,024-bit keys, the encryption is not practically breakable by brute-force methods -- there are simply too many keys to put into the electronic lock.
What's the buzz?
PGP is available, in source form, for nearly all Unix machines. There are also DOS and Macintosh versions available in source and binary form. One of PGP's many attractions is its immense portability. Getting PGP, however, is not as trivial as finding the local ftp archive and slurping bits over the wire. Because it contains strong cryptography, PGP is export-embargoed in the U.S. -- it cannot be taken or sent outside of the country. There are versions of PGP developed outside of the U.S. that can be used in other countries, and can be imported into the U.S. safely.
To ensure that only U.S. citizens currently living in the U.S. retrieve PGP, the primary distribution site at MIT makes you go through a short question-and-answer session. Telnet to net-dist.mit.edu, with a login of
<font face="Courier">getpgp</font>, and answer the questions posed to you. You'll be given a directory on that machine from which you can fetch PGP via anonymous ftp. Do so quickly after filling in the questionnaire, because the directory changes frequently. For more information, check out the MIT distribution site's home page.
Should you have Windows users who will snarl and gnash their teeth at a command-line driven utility, grab a copy of Christopher Greib's WinPGP from his home page (http://ourworld.compuserve.com/homepages/CGeib/). Version 4.0 of WinPGP runs under Windows95. And again, if you retrieve the code, don't redistribute it or send it out of the U.S., even to a co-worker, unless you particularly enjoy federal investigations. We'll briefly look at export controls and related issues next month, but for now take heed of the fact that the U.S. government only recently dropped charges against Phil Zimmermann for "distributing" PGP outside of the U.S. by posting it to USENET. If convicted, Phil would have faced up to 51 months in jail. Think carefully before sharing the goods.
Much of this month's column comes from Simson Garfinkel's outstanding book, PGP: Pretty Good Privacy published by O'Reilly & Associates. It contains a history of the package, details on every option and feature, and usage caveats. Peter Kent's PGP Companion for Windows published by Ventana Press, covers the package in less detail but describes the WinPGP Windows GUI that overlays it. If you are still interested in the theory of large numbers, primes, factoring, and the acronyms listed above, get a copy of Bruce Schneier's Applied Cryptography, published by Wiley. Now in its second edition, this book is the definitive bible on cryptosystems.
Armored transport: sending secret stuff
Enough politics and theory, let's blast bits. We'll postpone a discussion of how you collect, manage, and locate public keys, and instead go through the basics of using PGP to encrypt and decrypt messages. The simplest task to perform is encrypting a file (note that PGP normally produces quite a few time and copyright messages concerning the use of RSA, which we have elided here for space and clarity):
<font face="Courier"> huey% pgp -c message You need a pass phrase to encrypt the file. Enter pass phrase: Enter same pass phrase again: Just a moment.... Ciphertext file: message.pgp </font>
PGP asks for a pass phrase, which is simply a long password. The longer your pass phrase, the harder it will be for someone to guess it and decrypt the file. PGP produces the output file message.pgp, which can be turned back into plain (decrypted) text using PGP without any options:
<font face="Courier"> huey% pgp message.pgp </font>
Don't try to view the encrypted file with an editor or
<font face="Courier">more</font>, since it is a binary file that will at the least wreak havoc with your keyboard driver. Be sure to remove the original, plain text version of the file (or have PGP do it for you using the
<font face="Courier">-w</font>option), or your encryption efforts are for naught. The conventional encryption feature of PGP makes it possible to standardize on PGP for all of your data-security tasks.
Let's actually swap secret bits with someone. Hand PGP the options
<font face="Courier">-eat</font>and the recipients' user ID (we'll send this to our buddy Pepe):
<font face="Courier"> heuy% pgp -eat message pepe Recipients' public key(s) will be used to encrypt. Key for user ID: Pepe <email@example.com> 1024-bit key, Key ID 13FAC021, created 1995/05/17 . Transport armor file: message.asc </font>
We'll come back to the user ID, and how it relates to a recipient and his or her key shortly. The options produce a message suitable for mailing:
- Encryption is turned on with the
<font face="Courier">-a</font>flag tells PGP to produce an ASCII output file. Most mailers can't handle a binary file, so use the ASCII option to perform the equivalent of a
<font face="Courier">uuencode</font>. In PGP-speak, the ASCII output is called an ASCII armor file or a transport armor file, and is given the .asc extension.
- PGP treats the message like a text file when the
<font face="Courier">-t</font>option is given. When this file is decrypted on a Macintosh or Windows/DOS machine, it will have the correct end of line characters inserted. Unless you're specifically encrypting a binary file (such as a data set), use the
<font face="Courier">-t</font>option to preserve your end-of-line boundaries.
Now that we have message.asc, we can simply drop it in the mail to Pepe:
<font face="Courier"> heuy% mail firstname.lastname@example.org < message.asc </font>
Very few people compose mail in a text file and then pipe it to mail. PGP's filter option (
<font face="Courier">-f</font>) makes it easier to combine the encryption and composition steps:
<font face="Courier"> huey% pgp -eatf pepe | mail email@example.com </font>
When Pepe gets this message, he'll save it to a file, and then use
<font face="Courier">pgp mail.asc</font>to unravel the encrypted contents. The decrypted message will be saved in file mail. PGP has an option called "For Your Eyes Only," specified by the
<font face="Courier">-m</font>flag, that only displays the data. Rumor has it the feature was added so that a certain recipient could use PGP without inadvertendly leaving messages from her lover on the disk where her husband would find them. If true, it's further proof that most solid advances in computer science are spurred by games, sex, or both.
There are a few things worth pointing out:
- ASCII armor files can get fairly large, and may be too large for some transports. By default, PGP limits a single ASCII armor file to 720 lines, breaking up large files into several armored transports. You can change the maximum armor file size in the PGP configuration file, usually kept in ~/.pgp/config.txt.
- Encrypting the file required only the recipient's public key, and
no key information of your own. As a result, only the recipient can
decrypt the file. You created it, but only the holder of the private
key can unlock the encryption done with his or her public key. You can
encrypt a file for multiple users by specifying them all on the
<font face="Courier"> huey% pgp -eat pepe marie sven yaya </font>Putting your own user ID in the list, or enabling the
<font face="Courier">ENCRYPTTOSELF</font>option in the configuration file, ensures that you'll be able to decrypt a file that you created.
- Your crypto-cognoscenti friends will quickly point out that PGP uses both private and public key encryption. They're right. PGP generates a random session key for each invocation. The session key is encrypted via a public key algorithm, so that it can be unlocked on the other end. The data, however, is encrypted using a private key algorithm. The session key and encrypted data get tucked into the PGP file. When Pepe decrypts the file, he first extracts the session key using the private half of his public key pair, and uses that key to unwind the encryption used on the message body. Public key encryption is simply too slow -- nearly 1,000 times slower than private key. A side effect of the public/private key combination is that subsequent encryption attempts on the same file produce different output files -- each one is encrypted with a different session key, and therefore each has different contents.
Hiding your privates: key management
Now that you've seen how the public and private parts of a key are used, it's time to generate your own and collect those of your friends. Keys are kept on key rings, similar in concept to physical key rings. By default, there are two key rings -- pubring.pgp and secring.pgp -- for your collection of public keys and your own private keys. You can add other rings for your co-workers, friends, and other circles of data exchangers as needed. Key rings live in ~/.pgp, along with the configuration file.
The first step is to create a unique key pair. This will add your own key to both the public and private key rings:
<font face="Courier"> huey% pgp -kg Pick your RSA key size: 1) 512 bits- Low commercial grade, fast but less secure 2) 768 bits- High commercial grade, medium speed, good security 3) 1024 bits- "Military" grade, slow, highest security Choose 1, 2, or 3, or enter desired number of bits: 3 Generating an RSA key with a 1024-bit modulus. You need a user ID for your public key. The desired form for this user ID is your name, followed by your E-mail address enclosed in <angle brackets>, if you have an E-mail address. For example: John Q. Smith <firstname.lastname@example.org> Enter a user ID for your public key: Hal L. Stern <email@example.com> You need a pass phrase to protect your RSA secret key. Your pass phrase can be any sentence or phrase and may have many words, spaces, punctuation, or any other printable characters. Enter pass phrase: Enter same pass phrase again: </font>
The first thing you need to specify is the length of the key you want. There are few reasons to use less than 1,024 bits, given the speed of most machines you'll be using for encryption. Key generation is a slow process, due to the large numbers being multiplied and reduced -- it takes about 40 seconds to create a 1,024-bit key on a SPARCstation 10. PGP then asks you for your user ID, which is typically your full name followed by your e-mail address in brackets. In previous examples requiring a user ID, the string supplied is used to search through the public key ring for a match in the user ID field. When we chose pepe as a user ID, we picked up the public key for
<font face="Courier">Pepe <firstname.lastname@example.org></font>.
Finally, you'll need to specify a pass phrase for your private key. This pass phrase is what protects your private key from exposure on your local machine. If you were wondering how you were supposed to remember a 1,024 bit key, the short answer is you don't. The private key is encrypted using your pass phrase, and the encrypted string is added to the key ring. Key point: don't forget your pass phrase, or you'll have to create new public keys and go through the distribution process again. Similarly, don't choose a trivial pass phrase, or interested parties will crack open your private key and use it to decipher your incoming messages.
Now that you have created a key, you can give it to friends and family. The easiest way to do this is to extract the key from your public key ring:
<font face="Courier"> huey% pgp -kx stern mykey </font>
This pulls the key for user ID stern out of the public key ring, and writes into mykey.pgp (the extension is filled in for you by PGP). Put this file on a floppy and give a copy to anyone wishing to send you encrypted files or mail. Hopefully, they'll exchange their public keys with you as well so you can reciprocate. If you want to send the public key via e-mail, extract it in ASCII armor:
<font face="Courier"> huey% pgp -kxaf stern mykey | mail email@example.com </font>
If you take a look at the key file, it's merely the public part of your key represented in ASCII, with an ASCII PGP wrapper around it:
<font face="Courier"> -----BEGIN PGP PUBLIC KEY BLOCK----- Version: 2.6.2 mQCNAzEHJg0AAAEEAK64kFTWbJEUabpYbNplqkQWppFovgm2h1SiBjvUPqBiTJxL 8CCB2wPaOi13yDHEX0hUPS1SwUnT/azGMSfs6ClHE1/VJ4rUrgq3/QvJqbLIX7zB KV2mnvKh5RsbmTXGgp5Ndu2A8aCHB/4LNva3JCzgIgHGZNgLGp+BYWW7p+VBAAUR tCBMb3UgU2Nod2FydHogPGxvdUB3b3JsZC5zdGQuY29tPg== =uMh6 -----END PGP PUBLIC KEY BLOCK----- </font>
When Pepe gets the file, he saves the message in a file and adds the public key to his key ring:
<font face="Courier"> huey% pgp -ka hiskey.asc </font>
PGP also has several options for managing keys, allowing you to edit your user name or pass phrase and to check (examine) keys in any ring.
Personal exchange gives you a high degree of confidence in the keys. Unless you have a malicious identical twin, someone receiving a floppy from you can rest assured that it contains your valid public key. Trading floppies in coffee shops is nice, but it's unlikely you'll be able to personally meet people from all over the world. If you need to rely on e-mail distribution, you need some additional guarantees that the keys you're getting are valid.
Practically safe hex: trust and validity
PGP key management is built on the principles of trust and validity. Before adding a key to your public key ring, you want to make sure that it's not from someone posing as the sender. If I want to intercept mail going between you and your manager, I can simply pose as your manager and send you a message saying "Here is my new public key, please add it to your PGP public key ring." Then as I watch messages go by, I can decrypt them using the corresponding bogus private key. This may work once or twice, until your boss complains that she can no longer decrypt your messages encrypted with PGP.
The questions you need to answer when adding a key are:
- Is this key valid? Is it really from the person who claims to have created it?
- Can I trust anyone who tells me this key is valid? I may give you a key for a mutual friend, and you decide to take my word that the key is authentic. But the further you go in the friend-of-a-friend food chain, the less you tend to trust people.
Would you loan your car to my best friend's friend? Even though individual relationships are built on trust, you shouldn't feel comfortable extending trust to an arbitrary degree of separation.
Trust and validity are established through key certification, or signatures on keys, and key fingerprints. A fingerprint is simply a 128-bit checksum of the key. View the fingerprint of a key using the
<font face="Courier">-kvc</font>option to PGP:
<font face="Courier"> huey% pgp -kvc pubring.pgp Key ring: '/home/stern/.pgp/pubring.pgp' Type bits/keyID Date User ID pub 1024/CA1D1839 1996/01/25 Hal L. Stern <firstname.lastname@example.org> Key fingerprint = E2 C4 A9 6C 5C D1 93 93 C3 0D D6 34 24 D3 55 7F 1 matching key found. </font>
When I send you my key, I can also send you its fingerprint via another channel: over the phone, on my Web page, or on my business card. Compare the fingerprint generated by PGP while adding the key to the one you collected out of band, and you can determine if the key has been tampered with in transit. If you feel comfortable with either the key distribution or the fingerprint distribution, then you should feel comfortable adding the key to your public key ring.
When you add a key, PGP checks to see if it has been certified by the presence of any digital signatures. If there are no signatures, PGP gives you the option of certifying the key by signing it. If you do, you are making an explicit guarantee that the key is valid; if you later distribute that public key to a third party, he or she will see a certified key with your signature on it.
When PGP is given a certified key, it asks if you trust the signer to introduce new keys to you. If not, then the key will not be certified in your key ring. When you add a key, you attribute a certain level of trust to the person; people you trust can certify keys to be added to your key ring. If you get a key from an unknown person, but someone you trust has certified it, PGP will assume that you will accept the key as well. The bottom line, again, is to be careful with delegating trust and accepting keys on blind faith. The key distribution and certification chapter in Garfinkel's book covers this material with some outstanding examples.
One-on-one key distribution is slow, and not always convenient. What do you do when you need someone's public key and can't wait for them to send it to you? Several public key servers are available, such as the MIT Web server (http://www-swiss.ai.mit.edu/~bal/keyserver.html). There are also e-mail-based public key servers, including email@example.com and firstname.lastname@example.org. Send mail with a subject of INDEX and you'll get a key directory; extract a single key with a GET. The MGET command fetches multiple keys, using regular expression syntax for the user names, and ADD submits your key to the server for public distribution.
King George should be able to read this: digital signatures
All of the PGP examples discussed to this point let you safely exchange keys and data with groups of users on a one-to-one or one-to-few basis. How do we solve the broadcast problem outlined in the introduction, where we want to check the authenticity of a message sent to an alias? In more general terms, how do we verify the identity of any message's sender? Having your public key means I can send you a private message without fear of interception. But how do you know the message came from me, and not someone pretending to be me who happened to have your public key? Digital signatures fill the technology gap.
The basis for digital signatures is a keyed hash, or a checksum that has been encrypted for verification. The most common keyed hash, and the one used by PGP, is called Message Digest 5 (MD5), created by Ronald Rivest of RSA fame. MD5 takes a message of arbitrary length and distills it into a 128-bit checksum. The algorithm is highly sensitive to minute changes in the input, so changing a single bit is enough to generate a completely different checksum. The possibility of MD5 collisions exists, that is, two messages that produce the same 128-bit hash value. However, the probability of encountering two messages with the same MD5 hash value is exceptionally low -- there are 2^128 hash values produced, or about 3 x 10^38. The number of MD5 output values is far larger than the number of documents, messages, and e-mails sent in any person's lifetime. There are some good MD5 tools on the Purdue COAST archive (ftp://coast.cs.purdue.edu/pub/tools/unix/md5). MD5 is also one of the functions used in the Tripwire package (ftp://coast.cs.purdue.edu/pub/COAST/Tripwire/), a security tool that creates a hash of selected files and directories on a regular basis to detect intrusion or unwanted modification.
Simply having the MD5 hash value isn't sufficient, because a forger could have modified the message and included the updated MD5 value. The sender needs to authenticate the message digest such that the recipient will know that only the sender could have created it, and that no other user could have modified the value along the way. Turning an MD5 hash value into a digital signature requires using the RSA public key cryptosystem yet again. The public and private key pairs unlock each other, that is, anything encrypted with your public key can only be decrypted with your private key. Conversely, something encrypted with your private key can be decrypted by anyone with your public key. But -- only you could have done the encryption, since your private key is secret and known only to you. Voila! A digital signature that only you can produce, and anyone holding your public key can verify.
PGP's digital signatures work by generating an MD5 digest and encrypting it with your private key. Anyone receiving the file decrypts the signature with your public key, and regenerates the digest to verify the message arrived intact. To sign an encrypted message, add the
<font face="Courier">-s</font>option to the PGP command line:
<font face="Courier"> huey% pgp -seatf pepe | mail email@example.com </font>
If you don't specify a secret key, the one added most recently to your private key ring is used. Since you're accessing a private key you need to type in the pass phrase to unlock it, encryption and ASCII armoring takes place as before, with the PGP signature added to the end of the file.
Now let's solve our mail-to-the-world problem. It's possible to sign a file without encrypting it. The signature verifies the identify of the sender and the integrity of the data; it's proof that the message is valid and binding. When the data is going to several hundred people, it's neither useful nor practical to encrypt it. By adding a digital signature you can verify that the message is being sent by an appropriate person. Sign an ASCII message by leaving out the
<font face="Courier"> huey% pgp -satf | mail all-company </font>
Looking at the message, and you'll see the plain text followed by a PGP ASCII-encoded signature:
<font face="Courier"> -----BEGIN PGP SIGNED MESSAGE----- this is a short message file -----BEGIN PGP SIGNATURE----- Version: 2.6.2 iQCVAwUBMQcqvL4vzh7KHRg5AQFJBwP9H2Wa/qezmMBTGNfbG1U/5UHyM1EANo4J upBYSS9JOVg+YHEi1jrVOwYwBsCE7byW1iHI+dNI10zjXCV81xe+HD6O9hjfJLlu 1j7TftaR0sUOlkliubzVuKSDNB/qvAbLM66TmD9XmX4Ys/nuFmDP5y/FGBle+O4T OXBg5ZmoKq8= =teUd -----END PGP SIGNATURE----- </font>
Want to prevent spoofing on a grand scale? Feed the all-company alias into a mail handler that verifies the PGP signature, using the sender's return address as a PGP user ID. If the signatures don't match, suspect the mail broadcast as a possible forgery or an inappropriate use of the all-company alias. Implementing this kind of safeguard requires a policy demanding the use of PGP, and educating folks on the ins and outs of PGP signatures. It's a small price to pay, however, for a sudden reduction in junk mail and jokes gone bad that reflect badly on you and your environment. Valentine's Day may break hearts, but you've got to protect the rest of your body, mind, and machine room the rest of the year.