Appendix C. Cryptography

Cryptography is surrounded in myths, politics, and passionate opinions. This appendix is intended to help you sort them out to the extent necessary to build a firewall. It is not a complete introduction to cryptography; instead, it’s a rapid tour of the essentials you’ll need to understand the rest of this book. In particular, we avoid going into details on how cryptographic algorithms actually work, focusing instead on their general properties. A number of books focus on cryptography; we particularly recommend Bruce Schneier’s Applied Cryptography, 2nd edition (John Wiley & Sons, 1995).

This appendix starts by discussing general issues in cryptography, then describes types of cryptographic algorithms and their uses, and finishes with some information about specific algorithms.

What Are You Protecting and Why?

For the most part, people use cryptography to protect information. Sometimes they are trying to keep something secret; sometimes they are trying to keep something from being changed; sometimes they are trying to ensure that the person responsible for something is clearly identifiable. But very few people use cryptography just for the amusement value.

In order to determine what you need from cryptography, you have to first know what you need to protect and what you’re trying to protect it from. For instance, suppose you are attempting to keep some piece of information secret. That might be a trivial piece of information that’s going to change again soon (for instance, what present you picked out for a friend’s birthday next week), or it might be an important piece of information that can be turned into cash any time in the next several years (for instance, the number of the credit card you just got). It might be the press release you’re going to make public next week, which commercial competitors may be actively trying to discover but will be pointless to conceal as soon as it appears in the newspaper, or it might be your government’s nuclear bomb plans, which professional spies are actively trying to discover and will still destroy the world no matter when they’re used.

Clearly, you’re going to want different things from the algorithms you use to protect these pieces of information. If you’re keeping the birthday present a secret, you want something that’s fast and easy to use; you don’t care much if it’s easy to figure out (unless your friend is a cryptographer who hates surprises). If you’re keeping a credit card number secret, you mostly care about how secure it is, but most of the time, people won’t be trying to find it out. If you’re keeping a press release secret from competitors, you only need to protect it until you release it; if you’re keeping nuclear bomb plans secret, you need to protect them forever.

Similarly, cryptography can be used to prove your identity (this is discussed later in this appendix). You may use cryptography to prove who you are when sending a note to a friend, when approving an expensive purchase at work, or when releasing a piece of software to the world. These things require different levels of certainty, last for different amounts of time, and require different kinds of infrastructure.

If you’re sending a note to a friend, the friend probably doesn’t need to be all that certain who it’s from; if somebody else pretends to be you, it will probably all get sorted out in the end, even if a certain amount of comedy or unpleasantness results. The friend needs to be able to verify your identity only when the message arrives. If the verification data isn’t good months later, that’s OK; the message is probably of purely sentimental value by then. You and the friend can set up a system between the two of you for verifying your identity; you don’t need a way that will work on a large scale. Finally, all your friend needs to know is that the message is from you. Presumably, anybody you consider a friend already knows who you are and why they want to read messages from you.

If you’re authorizing a purchase at work, there are legal requirements to be fulfilled. Those legal requirements demand a higher level of certainty. If somebody else pretends to be you, the company’s money is at stake, and the consequences include prosecution for fraud or incompetence. The legal requirements also demand that the information be verifiable for a longer period of time; not only does somebody need to be able to verify your identity when the purchase is made, they need to be able to verify it again during a later query or audit. Practical requirements also mean that there needs to be a consistent company-wide architecture for verifying your identity. It can’t be done differently for every employee, so an infrastructure of some sort is required. That infrastructure has to include not only identity data (“This is how you know it’s from Ethelraeda Perkins”), but also authorization data (“This is how you know Ethelraeda Perkins is allowed to authorize purchases up to $20,000”).

If you’re releasing software to the Internet, things change again. If somebody pretends to be you and releases destructive software in your name, your reputation can be permanently damaged, and the consequences include things like your name ending up on the front page of newspapers worldwide. You need a high level of certainty about identities, and you need that level of certainty for a long time (one of the authors still periodically receives questions about relatively obscure software distributed over 10 years ago). This has to be provided with a worldwide infrastructure, accessible to everybody you want to distribute software to, and that infrastructure must provide enough information so that people can readily tell not only who you are, but why they trust you enough to run programs you’re distributing.

Key Components of Cryptographic Systems

Cryptography is used for multiple things, and cryptographic systems are built out of multiple parts. Encryption is the best-known and most obvious technique, but in order to understand how cryptography is used, you need to understand several other techniques as well, including those used for cryptographic hashing, integrity protection, and the generation of random numbers.

Encryption

Encryption is the process of reversibly hiding information. When you encrypt something, you take a piece of data (called the plaintext) and apply a process that produces another piece of data (called the ciphertext). There must also be a process for turning the ciphertext back into plaintext.

It’s not practical to think up a new algorithm every time you want to encrypt something. Useful encryption algorithms therefore use an extra piece of data called a key. In order to decrypt data, you need not only the decryption algorithm, but also the key; this means that you can use the same algorithm to encrypt different things and share them with different people. If an encryption algorithm doesn’t use a key, then as soon as you know the decryption algorithm, you can decrypt all the things encrypted with the algorithm.

Cryptographic wisdom considers an encryption process secure when the only way to recover a plaintext message from ciphertext is to know or discover the key. Furthermore, this rule should still be true even if every other detail about the encryption process is known. In fact, cryptographers become very concerned about the security of an algorithm when more than a key must be kept secret (for instance, when the algorithm or an important part of it is not disclosed).

There are some things that encryption cannot do. When you encrypt something, you conceal its content, which doesn’t necessarily conceal everything useful about it. Attackers may be able to gain important information by looking at the lengths of messages, or the times they’re sent, or the senders and receivers; none of that will be changed by encryption.

Furthermore, encrypting something does not protect it from being changed. Somebody who has access to the ciphertext can change it. They won’t be able to predict exactly what plaintext you’ll get, but it will almost certainly be different. This sort of tampering is normally easy for a human to detect in text but not so if the plaintext was binary data. Since computers are unable to comprehend text, they cannot detect tampering by inspection as humans can. In order to protect a message from modification, and in a way that a computer can detect, you must use integrity protection, which we will discuss. Although some integrity protection systems use encryption, encryption by itself does not provide integrity protection.

Kinds of encryption algorithms

There are two main families of encryption algorithms: symmetric and public key. A symmetric algorithm uses one key for both encryption and decryption. A public key algorithm uses two matching keys; when you encrypt with one of the keys, you use the other one to decrypt.

The primary characteristic of an encryption algorithm is its strength, which is the amount of effort it takes for somebody to turn the ciphertext into plaintext without having the key. There’s no absolute measure of the strength of an encryption algorithm. It’s possible to say that some algorithms are very weak (for instance, replacing every letter with the letter three characters later in the alphabet, so that “b” becomes “e” and “c” becomes “f”, is definitely a very weak algorithm), and it’s possible to say that some algorithms have no known weaknesses. When we discuss particular algorithms, we will mention algorithms that are known to be attackable, or weak. A wide range of algorithms are available that don’t have known weaknesses, and in most circumstances, you can and should choose one of them.

In the real world, strength is not the only important characteristic of an encryption algorithm. Some algorithms are much faster to execute than others, for instance, and the speed may depend on the kind of processor you have available. Some algorithms require more memory than others. Some algorithms have legal restrictions on their use, which are different in different countries. Some algorithms are patented and are expensive or difficult to license.

Public key and symmetric algorithms differ on all of these fronts (most notably, symmetric algorithms are much faster than public key algorithms), but the most important difference between them comes from the extra capabilities of public key algorithms. With a symmetric key algorithm, anybody who can encrypt a message can also decrypt the message, and it is therefore important to keep the one key secure so that it is known only by the parties who are trying to communicate. With a public key algorithm, you can make one key public while keeping the other one completely private, so that only you know it.

Having a public key and a private key opens up a number of new uses of cryptography. For instance, if you encrypt something with your private key, you don’t keep the data secret (anybody who has the public key can read it), but you do prove that you encrypted it (because only you have the private key). This is called signing. Digital signatures are discussed in detail later in this appendix. Anybody who wants to send you something secret can encrypt it with your public key, and be sure that only you can read it. In fact, some ways of using public key technology don’t actually allow you to conceal data; you can only use them for authentication; some public key algorithms are not encryption algorithms.

Just as there are differences between public key algorithms and symmetric algorithms, there are differences among symmetric algorithms. Some work on fixed-sized chunks of data and are called block ciphers. Others, called stream ciphers, work on an arbitrary sequence of bits or bytes. There are various ways, called modes, to extend a block cipher so that it can encrypt more than just a single block of data. Stream ciphers are naturally designed to handle an arbitrarily sized stream of data.

The encryption of variable amounts of data is usually called bulk encryption. In this case, anything bigger than about 64 bits is considered “bulk”. Almost all bulk encryption is done with symmetric algorithms because of the speed difference between symmetric and public key encryption. It is frequently desirable to use bulk encryption in situations where the communicating parties don’t already have a common symmetric encryption key. An extremely common way to solve this problem is to combine public key cryptography with symmetric key cryptography. For instance, the PGP package, commonly used for bulk encryption of electronic mail, uses a symmetric key algorithm to encrypt the body of a mail message, and then uses public key encryption to encrypt the symmetric key and sends the encrypted symmetric key with the message.

Encryption algorithms and key length

One of the important ways algorithms differ is in the keys they use. As we’ve discussed before, in order to decrypt something that was encrypted with a strong algorithm, you have to know what the key is. Therefore, one way that people attack encryption algorithms is to try to figure out the key. There are obviously many ways to go about this, most of which are not under the control of the encryption algorithm (for instance, you can go around looking for places where the key is recorded and not adequately secured).

However, some ways of figuring out keys are based on how the algorithm works. With a symmetric key algorithm, the easiest way to figure out a key is to try all the possible keys until you find the correct one (knowing you have found the correct key is a separate, and tricky, problem). The more possible keys there are, the harder it is. With a public key algorithm, you can try to calculate a private key based on the public key using existing mathematical techniques if you know that you have a fast enough computer with enough memory, or you can invent a new mathematical theory for solving the equations used in the public key algorithm. Either of these methodologies will be easier than trying all possible private keys.

For any given algorithm, the longer the key is, the harder it is to find it out. On the other hand, you can’t directly compare key lengths between different kinds of algorithms because the ways that they can be attacked are different. A 128-bit key is a pretty strong key for a symmetric algorithm but a pretty weak one for most public key algorithms. This is because 128 bits is a lot of keys to search but not large enough to prevent mathematical attacks on public key algorithms. Since different public key algorithms use different relationships between the private key and the public key, key lengths can’t always be compared even between different public key algorithms.

If you know that trying all possible keys is the only way to find a key, you can be reasonably confident about your security; the speed of light imposes a theoretical limit on how fast computations can be performed, so if the key is big enough, nobody can be sure to find it within the estimated lifetime of the universe. (It’s always possible to get lucky when you’re trying keys, but you’re much more likely to win a lottery.) The key length required to be big enough is surprisingly short; it’s under 128 bits.

The situation with public keys is not as simple. Currently known techniques for finding private keys are difficult on today’s computers, but it has yet to be proven that there are no faster techniques.

It’s important to distinguish between key length and block length when discussing block ciphers. These are often but not always the same, and the block length is the length most often given. When somebody refers to a “64-bit block cipher”, that is the length of the block, and not necessarily the length of the key. This can be horribly confusing, since for other ciphers the key length is the only thing normally specified in bits like that. Pay close attention to which length is being specified; a “64-bit public key algorithm” has a 64-bit key, while a “64-bit block cipher” might have any key length at all.

Cryptographic Hashes, Checksums, and Message Digests

A checksum is a number calculated on a given set of data that is designed to detect changes or errors in communication of that data. This is useful for a communications channel; if a sender calculates a checksum as data is being sent and a receiver does the same as it is being received, the two can simply compare checksums to see if the data arrived intact or if an error occurred during transmission. Another use might be to store the checksum and then repeat the calculation at a later time. If the two checksums are different, then something changed in the data.

A checksum is usually just several bytes long and will take up much less space than the original data. While this makes them easier to store, it also means that there must be situations where a checksum will give the same answer for two different pieces of data. This is called a collision, and checksum algorithms are designed to make collisions unlikely to occur for the differences they are designed to detect. Checksum algorithms for communications are designed to detect random bursts of errors or chunks of missing data because they are the kinds of differences that you often get on a telephone line or a radio transmission (to humans listening, these errors sound like clicks or pops).

What if the error was not random and a deliberate change was intended? If so, is it possible to make a deliberate change and keep the checksum the same? For many checksums, this is certainly possible because the checksums are not designed to make this difficult. There are ways to design checksum algorithms so that it is impossibly difficult to make a deliberate change and still have the checksum match. Algorithms designed this way are called cryptographic hash functions, cryptographic checksums, or message digest functions.

Note that the terminology used for the different techniques and uses of cryptographic hashes is confusing and overlapping. As a result, terms are not used very consistently; about the best you can say is that any term involving integrity, digest, or the acronym MAC (Message Authentication Code) probably refers to some process that uses some kind of hash. If you care about the details, investigate them, rather than trusting that terms are used consistently from one document to another.

The term hash comes from another situation where it is useful to have a short fixed-length string that you can generate consistently from a larger string and that has large changes in the output as a result of small changes to the input. Hash algorithms and checksum algorithms are not always used for the same purposes, but if you extend either concept for cryptographic security, you reach the following set of conditions for a cryptographic hash:

  • It must be practically impossible to deliberately create data that has a hash value that matches another. This can be achieved by designing the algorithm so that it cannot be reversed and run backwards (you can’t start with a hash value and use a method to create data that computes to the same hash).

  • The hash must be of a large enough size so that you cannot create a list of files, one for each value the hash can have, and match a given hash that way. In practical terms, this means that a useful hash should be at least 128 bits and preferably 160 bits or more in size.

  • If you change something only very slightly in the data, the hash will change by a large amount. Changing one bit in the data should change about half the bits in the hash. This makes it hard for people to slowly adjust individual bits in the data to achieve a desired hash value.

There are two principal uses for cryptographic hashes. First, they are used to detect changes in data. If you have a cryptographic hash for a piece of data and the hash is kept secure, you can be sure that if you recalculate the hash and it is the same, then the data hasn’t been modified. This is the basis for digital signatures, which are discussed later in this appendix.

Cryptographic hashes are also frequently used in authentication systems. In most cases, passwords are not encrypted, but hashed. If you use encryption on a password, it is possible to decrypt it and get back the password, which an attacker could then use somewhere else. This makes storing and sending encrypted passwords dangerous. Instead, secure systems store a hash of the password and, when a user wants to authenticate to the system, compute a hash of the password provided by the user. If the hashes match, the user must know the correct password.

This technique does not help if a user can directly provide the hash, instead of the password (for instance, if the user is logging in over a network and what the system actually receives is the hash). If the hash is sent around, it simply becomes another fixed and reusable password. (This is discussed further in Chapter 21.) For this reason, good network authentication systems use a random piece of data that changes on every transaction, often called a nonce. Adding this changing value into the information that gets hashed and exchanged prevents eavesdroppers from reading and reusing the hashes.

It is possible to use a block cipher in a special way to calculate a cryptographic hash. When a cipher is used like this, the resulting checksum may be called a Message Authentication Code (MAC), a Message Integrity Code (MIC), or a Message Digest Check (MDC).

The use of block ciphers for calculating cryptographic hashes is often seen in older cryptographic protocols. In particular, they frequently use the Data Encryption Standard (DES) to produce 64-bit values. Most modern cryptographic protocols explicitly use cryptographic hash algorithms. One reason is that cryptographic hash algorithms tend to produce results that are 128 to 160 bits in size. This significantly reduces the chances of being able to come up with a different piece of data that produces the same hash value.

Integrity Protection

One of the most important uses of cryptographic hashes is to provide integrity protection. A cryptographic hash can be used to verify that no changes to data have been made, but this won’t work if you include the hash value with the data. All someone wishing to change the data would have to do is replace the hash value with a new value computed from the changed data. Some way is needed to protect the cryptographic hash from being changed to the desired new value.

One way is to encrypt the cryptographic hash using a public key algorithm; this is essentially a digital signature, as we discuss later. Because of the slowness of public key encryption, it is not always a usable solution. Alternatives have been developed that are based on the calculation of cryptographic hashes, which include a secret key as part of the calculation. Without that key, someone wishing to change the data cannot recalculate a new and valid checksum. Many recent Internet protocols use a method called HMAC[1] for combining a key with a cryptographic hash. The HMAC technique can be used with any cryptographic hash function that produces at least 128 bits of output. HMAC is described in RFC 2104.

Random Numbers

Many parts of cryptography depend on being able to generate random numbers, or at least numbers that can’t be predicted. For instance, if you need to send authentication information across the network in a form that’s not reusable, you will want an unpredictable changing value to add in with the information. If an attacker can figure out what that value is, the attacker may be able to use the value to authenticate or to figure out the authentication data for later use.

Computers are very bad at being random because they are designed to be able to repeatedly calculate the same answer if given the same data to work with. If you have an algorithm for giving you random numbers, you will get the same list of random numbers whenever you run it. This is why random number generators on computers are called pseudo-random. Knowing the algorithm and the starting information, and having a faster computer, would allow you to predict what the numbers were going to be. Truly random numbers cannot be predicted.

So where can a source of acceptable random numbers come from? It is easy if the computer has some hardware to generate random numbers; if not, then some random information can be obtained from peripheral devices attached to the computer. It has to be done very carefully because it is easy to overestimate how random some sources of information are. Sampling a fast running clock is not really a good way to get random numbers because typically only a small number of bits will change each time the clock is sampled.[2]

Several free Unix operating systems, including Linux, have special code as part of the low-level device drivers, which continuously collects random input events from the keyboard and other hardware devices and allows applications to obtain a source of random data.

Combined Cryptography

The basic building blocks (encryption, cryptographic hashes, and random numbers) can be put together to create various larger systems that meet needs beyond simply hiding data. These include digital signatures and certificates.

Digital Signatures

What is a digital signature ? It is the digital equivalent of putting your signature on a document. When you sign a paper document, you are permanently attaching something that identifies you with a particular piece of information. The assumption is that only you can create your signature and your signature cannot be transferred to another document.

Normal signatures are relatively easy to work around. For instance, somebody can forge your signature, photocopy your signature, and stick it on another document, or change the document after you’ve signed it. Over the years, people have developed a number of systems to help prevent these kinds of attacks, with varying amounts of success. This includes ways of telling originals of documents from photocopies (ranging from the simple trick of signing in a pen that’s not black[3] to complicated ways of making documents that don’t photocopy well), systems where you sign and date every page of a document to keep people from substituting pages, and ways of physically protecting multiple copies so that nobody can modify them all. None of these systems is foolproof.

Digital signature algorithms try to provide a much more consistent set of guarantees, with mixed success. Digital signature technology combines public key cryptography and cryptographic hashing; public key cryptography provides a way to prove your identity, and cryptographic hashing provides a way to guarantee that the information to which you attached your identity has not been modified.

Tampering is prevented by using a cryptographic hash function to generate a hash of the document or data. The hash is then combined with the private key using the digital signature algorithm to produce something that can be produced only by you and is bound to a particular piece of data.

When you sign something, you use your private key; when recipients get the signature, they use your public key to verify it. This means that recipients must have access to a reliable data source that includes your public key information. This is identical to the paper versions. Organizations that are serious about signatures (banks, for instance) keep a sample of your signature on record so that they can make comparisons. Anybody who can replace that sample can authenticate as you.

A private key is an important authenticator, like a physical credit card. If you lose control of your credit card, there is a possibility that somebody else will use it, and you will need to make that credit card invalid. If you destroy the credit card accidentally, you need to get a new card, but there’s no particular need to make the old one invalid.

The only person who should have the key you use to make signatures is you—there should not be any copies of the key. Somebody who has a copy of the key can pretend to be you. On the other hand, if you lose the ability to use your key, it does not prevent already signed documents from being verified, and nothing prevents you from generating and using a new key.

In order to be successful, a digital signature system not only has to provide an algorithm that lets you sign something, it also has to provide the infrastructure that lets people verify that signature. That infrastructure has to support a number of operations. You need to be able to generate a new key if you can’t use the old one, and you need to be able to cancel a key if you lose control over it. The process of canceling a key is called revocation, and it is one of the hardest parts of successfully designing a digital signature system.

Certificates

What is a certificate ? A certificate is a digitally signed piece of binary data that contains a set of public keys, some attributes and values, and an expiration date. Some of the values are designed to be displayed to humans, and others are intended for use by programs. Humans are interested in things such as names, the organization you work for, or your telephone number. Programs may be interested in things like your public key, your employee number, or the identifier of your manager. Sometimes values like an electronic mail address are useful to both humans and programs.

A certificate has similarities to a driver’s license or a passport. These physical documents are deliberately made to be difficult for ordinary people to duplicate or alter because they are often used when you need to prove your identity. The authorities or organizations that create these documents usually go to some length to make sure they are given to the right people. This is because the organization ends up being a common point of trust between you and whomever you show the documents to.

There is one crucial and very important distinction between a signed digital certificate and a physical document such as a driver’s license or a passport. The digital signature on a certificate is designed so that it cannot be forged; it doesn’t matter how good you are with computers or with guessing numbers; your chances of being able to fool someone with a made up or altered certificate are impossibly small. There are, of course, ways to trick people into issuing real documents containing bogus information, and just as in the real world, it is possible with digital certificates. If the cryptography is sound, then it is really a problem with people or the processes used to create digital certificates, not a flaw in the certificate itself.

So who digitally signs a certificate? As in the real world, it is useful for a common point of trust to digitally sign a certificate. This might be the organization you work for or some externally recognized authority, depending on who you want to communicate with. In order for a certificate to be useful, the receiver has to be able to verify that it’s valid.

In order to perform this verification, the receiver has to establish a connection from some certificate that the receiver knows is OK to the certificate in question. There may be additional certificates that must be checked in order to go from the entity who the verifier trusts to the certificate being checked. The connection between the common point of trust and the certificate being checked is called the trust path, and the collection of all the certificates is called the certificate chain. If all of the certificates in the trust path are valid, then the certificate verifier will trust the certificate.

This kind of process goes on with physical documents as well, but it’s much slower, and the responsibility is all on the certificate holder. For instance, if you want to write a check to the grocery store, you will be asked for identification. Most grocery stores won’t accept out-of-state driver’s licenses for identification; they can’t verify the validity of the license. But if you want to get a local driver’s license, the license bureau will accept your out-of-state driver’s license, allowing you to build up a certificate chain that lets you successfully authenticate to the grocery store.

What can a certificate be used for? A certificate can be used to provide information about your identity to someone you have not previously arranged to share information with. Certificates are often used as a way to verify public keys, for example. But they will work only if there is a common point of trust between you; everybody involved has to trust a common certificate authority.

In order to potentially be able to use a digital certificate to communicate with anyone alive, you need to have a common standard and a global infrastructure that supports certificates. There are currently two certificate standards being proposed for use on the Internet. One is called Simple Public Key Infrastructure (SPKI), and the other is called Public-Key Infrastructure X.509 (PKIX).

These certificate formats have some things in common. One common value in the contents of a certificate is an expiration date. An expiration date means that a certificate has a lifetime, and beyond that point, you will no longer believe that the contents of the certificate are valid. If a key is to be used beyond that point, the certificate will have to be re-signed.

Another thing in common between the design of the two infrastructures is a way to handle the situation when a certificate becomes invalid. This is the same problem we discussed previously for digital signatures; there needs to be a way to make a certificate unusable. For instance, certificates that contain public keys need to be made unusable if you want to tell people to stop using a public key, either because the private key is no longer available (so that messages encrypted with the public key are no longer readable), or because somebody other than the original holder has access to the private key and it can no longer be trusted. A certificate authority might also want to get rid of a certificate for other reasons (the authority might discover that the certificate holder lied about some of the information in the certificate or that the certificate holder’s check bounced).

In all of these situations, you no longer want the certificate to be thought of as valid, but if this occurs before the certificate expires, there must be a way to get rid of it, which is called revoking the certificate. You cannot just get rid of the copy of the certificate that is at the certificate authority because anyone with a local copy will still use the certificate, without knowing that there’s something wrong with it. What usually happens is that the key is placed on a special list, and for PKIX, this list is called the Certificate Revocation List (CRL). When someone wants to use a certificate, he or she first checks to see if it is on the CRL. If it isn’t, then the certificate can be used. A revoked certificate needs to remain on this list until the certificate expires.

The CRL creates a problem; if you give a certificate a short lifetime, you will need to keep regenerating certificates, but if the lifetime is too long, you may need to keep a large CRL. The parameters for these things will depend entirely on the use of certificates. If you were a university, then you might wish to issue certificates with a lifetime of a year if you didn’t want to continually sign certificates. On the other hand, you might choose to expire certificates at the end of each session of classes if you thought that lots of people will lose their certificates or need them revoked. An additional problem with CRLs is that they must be available when performing authentication. This can be difficult if, for example, your network is not working, and you are trying to authenticate the instructions to fix it.

Certificate Trust Models

A trust model defines the ways in which certificate authorities build up a chain of trust, so that two widely separated entities can find a common trusted authority. There are two basic certificate trust models. One is strictly hierarchical, and the other is a mesh.

The hierarchical model is like a chain of command and is frequently represented as a tree (this is a tree as in the data structure used in computer science). If you pick any two parts of the tree, it is always possible, by going upwards in the tree, to find a point where the two parts join. It is a very simple algorithm, and it always works. It is the model used by the PKIX standard.

To implement such a model globally you would need quite a large amount of infrastructure, not to mention dealing with the political wrangling for who wants to be at the top. For this reason, the PKIX standard allows a number of separate trees to be joined (which is called cross certification). This means that there can be a number of trees. However, the top of each tree is then made to be part of every other tree (making a full mesh between the tree tops!). This means that if the trees are joined, there will always be a certificate chain to reach anyone else, although it may be a very long chain.

The other model is a mesh and is sometimes called a web of trust. In this model, connections can be made voluntarily between any two certificate authorities. If any two parts of a web of trust are chosen, there may or may not be a way that they are connected. This model is used by PGP. In fact, PGP normally uses a model in which individuals are themselves the certificate authorities, choosing which other keys they will sign, and which keys they will trust based on who has signed them.

In theory, a web of trust is not as reliable as a hierarchical model. In reality, when certificates are used to identify individual human beings, it is not usually a problem. People rarely spontaneously wish to communicate with strangers. Most interactions are between a known group of people. If a web already exists between these people and a new person joins, there will be a way for the new person to communicate with the rest of the group.

Key Distribution and Exchange

Before you can communicate any data using a symmetric key algorithm, you have to make sure that all participants have the same symmetric key. You can’t just send out that key the same way you’re going to send the encrypted data because then anybody who’s watching that channel will have the key (and if you don’t think anybody’s watching the channel, you don’t need to encrypt the data in the first place). If you’re using a public key algorithm, you have a different problem; you need to be sure that you have the correct public key for the entity you want to encrypt things for. These kinds of problems are called key distribution problems.

There are three common ways for symmetric keys to be distributed. The first method is called manual keying, which simply means that there is no defined way for the key to be distributed and some human being has to get it in. The assumption is that the human will get the key via some reasonably secure method that can’t be compromised by the same techniques that would compromise the encryption system itself (so, for instance, if the encryption system is for a network protocol, the key will be sent via fax, not over the network).

Manual keying is regrettably common in systems that use long-lived keys and is bearable only in such systems; if you have to change keys frequently, having people involved is unusably slow and error prone. In addition, people frequently compromise manual keying systems (for instance, by sending keys in unencrypted electronic mail or by leaving the fax of the key lying around where attackers can find it).

Symmetric keys may also be distributed using public key cryptography ; this simply changes the problem to one of public key distribution, which we’ll discuss later. In systems that do this, one party decides on a symmetric key and encrypts it using the other party’s public key. As long as the public key information is trustworthy, only the desired other party can read the symmetric key.

Finally, symmetric keys may be distributed using a key exchange algorithm. Key exchange algorithms are a special class of public key algorithms that don’t encrypt data but do allow two sides of a transaction to figure out the same unpredictable number. The basic principle behind current algorithms is that each side picks a random number, performs a calculation on it, and sends the other side the result. Each side then performs another calculation, still using its original random number, on the other side’s initial result, and the two sides come out with the same answer, which is used as a secret key. In order for this to be secure, it must be difficult for an eavesdropper who has the two intermediate results to calculate the final result.

Because public keys are not secret, they are in some ways easier to distribute than symmetric keys; you can send them around without trying to hide them. On the other hand, you need some way to verify that a public key is the correct public key for the entity you want to communicate with. If an attacker can convince you that the attacker’s public key belongs to a friend of yours, you will cheerfully encrypt all the data you want to send to your friend so that the attacker can read it (but your friend can’t).

There are two common ways to verify a public key. First, you can use a certificate authority (certificates are described earlier). Second, you can use external means to verify the key. One way, which was made popular by PGP, is to verify a key’s fingerprint. A fingerprint for a key is usually a hexadecimal representation of a cryptographic hash of the public key. External verification of public keys, like manual exchange of symmetric keys, is flexible but clunky. In practice, keys that require external verification are almost never verified. It is also important to verify a fingerprint independently from the source used to obtain the public key. For instance, if your software vendor prints the fingerprint of a public key on the CDs they send out, then a suitably able attacker could produce similar CDs using a fake public key and print the bogus fingerprint on the CD.

What Makes a Protocol Secure?

The encryption algorithm is not the only thing that determines how secure a transaction is. Knowing what encryption algorithm is being used is like knowing what kind of safe somebody owns; it doesn’t tell you anything about how secure the information actually is. You can have a completely burglar-proof safe but never bother to put documents in it, or put documents into it without locking the safe, or put documents into it and lock the safe using a combination that lots of people know or can guess.

Just as many people buy expensive and secure safes and use them badly, many people take good encryption algorithms and build them into insecure systems.

In order for a client and a server to have an authenticated and secure private communication session, the following are needed:

  • The client and server must agree on what cryptographic algorithms they wish to use.

  • The client must be able to tell it is talking to the right server, and the server must be able to tell what client it is talking to.

  • The client and server must share a secret that nobody else can know or independently determine.

  • The client and server must be able to tell if someone has altered any messages (particularly during the initial stages of communication).

  • At the end of the session, the shared secret must be destroyed, and there should not exist a way for it to be recreated.

Selecting an Algorithm

In a perfect world, it would be possible to select the perfect encryption algorithm for clients and servers to use once, and no negotiation would be necessary. The real world doesn’t work this way. Sometimes it’s necessary for some clients or servers to use relatively weak encryption (either because they have computational limits and can’t do stronger encryption fast enough to keep up, or because legal or licensing restrictions control what kind of encryption they can do). In this situation, you don’t want to hold back all connections to the lowest common denominator, so you need to support negotiation.

Even when this kind of negotiation isn’t needed, most protocols support negotiation in order to allow future implementations to change the encryption algorithm that is used. New encryption algorithms are frequently discovered, and so are new problems with old encryption algorithms. You don’t want to be stuck using an encryption algorithm that somebody has figured out how to decrypt easily, or an algorithm that’s half the speed of the newest and best thing. Once again, you need to be able to negotiate.

Safe negotiation is difficult. It should be possible for each end of the connection to specify what algorithms are acceptable. If one end can convince the other to negotiate little or no security, a hostile client or server can force connections that will leak information. Even more importantly, it should not be possible for any third party to influence the negotiation. You do not want an attacker to be able to select the encryption that’s easiest to break!

A secure protocol uses a negotiation that:

  • Allows each side to specify an ordered list of algorithms (from the most desirable to the least desirable)

  • Always selects the most desirable possible algorithm

  • Fails altogether if no algorithm is acceptable to both sides

  • Uses message integrity protections to prevent third-party tampering (see the earlier discussion for more information on message integrity)

Mutual Authentication

In general, when people worry about authentication, they worry about client authentication; how does the server tell that it is offering services to the right client? In a secure protocol, it is also important for the client to be sure about what server it is talking to. The client is going to offer authentication data to the server. That authentication data is valuable to an attacker, and you don’t want to blindly hand it out to anybody that asks.

A secure protocol therefore provides for mutual authentication; the server authenticates itself to the client, and the client authenticates itself to the server. There are various ways of doing this, most of them based on the same trick where each side proves that it can decrypt a value with a secret that only the authentic participant could know. This secret could be a key used with a symmetric algorithm, or it could be the private half of a public key/private key pair; it makes a difference in configuring the servers and clients but doesn’t change the basis for the authentication. In either case, each side sends the other an unpredictable value and gets it back in a form that proves the other side could decrypt it.

Sharing a Secret

As we’ve mentioned before, public key cryptography is slow. Very few network protocols can rely on public key cryptography to protect data simply because it takes too long. Protocols therefore need to have a shared secret that can be used for symmetric encryption. That secret can be something they both know already, but there are a number of reasons why it is convenient to use a temporary key (sometimes known as a session key) for most transactions, and to discard the key when the transaction is over:

  • In general, the more ciphertext that uses the same key that is available to an attacker, the easier it is for the attacker to discover the plaintext (this is particularly true of one of the fastest classes of encryption algorithms).

  • The longer a key is in existence, the more likely it is to be inadvertently disclosed.

For these reasons, secure protocols negotiate a key to be used for symmetric encryption for a single transaction. This key needs to be unpredictable, so some random numbers need to be involved in the process.

Identifying Altered Messages

Encryption by itself will not keep people from altering data. A secure protocol needs to add something that will. In general, it will be some form of message integrity checksum, as discussed earlier in this appendix in the section about integrity protection.

Destroying the Shared Secret

Once you have decided to use a temporary shared secret, it is also important to destroy the secret when you are done with it. If there is a way to recreate the secret, then someone who recorded the session could, once they had the right information, decrypt it. If there is no way to recreate the secret, even with unlimited access to the computers on both sides of the communication, then you have achieved a cryptographic property called perfect forward secrecy.

Perfection is normally difficult or expensive to obtain, and perfect forward secrecy is no exception. In general, temporary keys are generated using information that is available to one or both sides of the transaction, and there are also usually situations where one side or the other is not sure whether or not the transaction has completed, and needs to keep the key around until the situation is clarified. For practical reasons, most systems implement partial perfect forward secrecy, where there is some period of time during which it is possible to recreate the shared secret. After this time period, things are reset, and the secret is destroyed.

Information About Algorithms

In this book, we frequently refer to specific cryptographic algorithms. This section is intended to give you some information about the specific algorithms that are frequently used in firewalls and network protocols, allowing you to make some comparisons between them. It is by no means an exhaustive listing of cryptographic algorithms that you may encounter, or of all the interesting information about the listed cryptographic algorithms.

Encryption Algorithms

These algorithms are designed to be used for encryption (reversibly obscuring information). As we’ve mentioned, it is often possible to use encryption algorithms for other purposes, and many of these algorithms are also used for digital signatures and/or for cryptographic hashing.

Rivest, Shamir, and Adleman (RSA)

RSA is a public key cipher that can use varying key sizes (which are theoretically unlimited). Typical key sizes are 512, 768, 1024, and 2048 bits. Because the algorithm is expensive to compute, the smaller key sizes tend to be seen in smart cards and smaller devices. A 1024-bit key is considered suitable both for generating digital signatures and for key exchange when used with bulk encryption. A 2048-bit key is sometimes used when a digital signature must be kept secure for an extended period of time. One such use is for a certificate authority key.

RSA was developed in 1978 by Ronald Rivest, Adi Shamir, and Leonard Adleman. Mathematically, it is arguably one of the simplest public key algorithms to understand and implement. The RSA algorithm obtains its strength from the belief that it is difficult to factor large numbers. The RSA algorithm is patented, although the last patent that is believed to cover the algorithm runs out on 20 September 2000. When implemented in software, RSA with 1024-bit keys is about 100 times slower than DES and gets much slower as the keys get larger.

The Data Encryption Standard (DES) and Triple DES

DES is a symmetric 64-bit block cipher that uses a 56-bit key. It has been demonstrated[4] that it is possible, with a modest investment, to build a specialized piece of hardware that can break a 56-bit DES key in about 24 hours. A group of individuals using a large number of general-purpose computers was able to break a 56-bit DES key in about three months. This size key is probably too short for protecting anything of significant value.

Triple DES (3DES) is a way of combining three uses of single DES with two keys, making the key size 112 bits. Because of the increase in key size, 3DES is believed to be much more secure than ordinary DES. 3DES runs about three times slower than single DES.

The DES algorithm was developed by IBM in the 1970s and was standardized by the U.S. National Bureau of Standards and Technology (the organization is now called the National Institute of Standards and Technology or NIST). It was intended for encrypting unclassified data. Some of the development process for this algorithm is shrouded in mystery, and the NSA had input into the design process that resulted in a number of modifications. The fact that nobody has been able to show that DES has significant weaknesses suggests that the influence of the NSA actually increased the strength of the cipher. It is not clear that the designers intended for the algorithm to be released to the public.

RC2 and RC4

RC2 is a variable key length symmetric 64-bit block cipher; RC4 is a variable key length stream cipher. The key size for either algorithm can be anywhere from 1 to 2048 bits long. The algorithms are typically used with 40-bit and 128-bit keys. A 40-bit key is too small to protect anything of any value but is widely used due to previous U.S. export rules, which prevented the export of products using longer keys.

These algorithms were developed by Ronald Rivest and are trade secrets of RSA Data Security. The RC4 algorithm was disclosed by a 1994 anonymous Usenet posting; RC2 met the same fate in 1996. Both algorithms seem to be reasonably strong. When implemented in software they are about ten times faster than DES.

Skipjack

Skipjack is a symmetric 64-bit block cipher. The key size is 80 bits long. Skipjack was originally developed as part of a U.S. government encryption standard that was designed to make it easy for law enforcement agencies to decrypt data (which requires using Skipjack in conjunction with a protocol called the Key Exchange Algorithm, or KEA).

Skipjack was initially available only in a hardware implementation called the Clipper chip. The algorithm was declassified in 1998 and can now be implemented in software (in this form, it does not necessarily include the provisions for law enforcement access). Research into the strength of Skipjack itself is inconclusive, but it has been shown that a slightly modified version of Skipjack can be broken without using an exhaustive key search. Skipjack does not seem to be a very popular algorithm to implement, possibly because of its history, and as such there is little comparative timing data.

International Data Encryption Algorithm (IDEA)

IDEA is a symmetric 64-bit block cipher that uses a 128-bit key.

IDEA was invented by Xuejia Lai and James Massey and released in 1992. It has undergone some extensive cryptanalysis and seems to be a strong cipher. The IDEA algorithm is patented in Europe and the United States and must be licensed for commercial use. IDEA is the symmetric block cipher used in Phil Zimmerman’s original PGP, one of the most widespread programs for exchanging arbitrary encrypted data across the Internet. There are no problems with the key size. When implemented in software, IDEA runs at about half the speed of DES, but one and a half times the speed of 3DES.

Blowfish

Blowfish is a symmetric 64-bit block cipher with a variable-length key. The key can be from 32 to 448 bits in size.

Blowfish was invented by Bruce Schneier and released in 1994. The algorithm appears to be strong. It is designed to be used on 32-bit microprocessors using simple mathematical operations. It does have larger memory requirements than other algorithms, which makes it less attractive for use in smart cards and other small devices. Blowfish is not patented, and implementations in C are in the public domain. When implemented in software, Blowfish runs at about five times the speed of 3DES.

Advanced Encryption Standard (AES)

The Advanced Encryption Standard is being set by the U.S. NIST organization, and the aim is to choose “a Crypto Algorithm for the Twenty-First Century”. AES is intended to replace DES as a U.S. government standard. Having learned from the problems with DES, NIST has chosen to use a public process to develop the standard and to include algorithms designed outside the United States. At the time of writing, a standard has not yet been set, but the following five algorithms are being considered: Mars, RC6, Rijndael, Serpent, and Twofish. Comparison data for all of these algorithms is available from NIST; they all appear to be strong algorithms. In order to meet the requirements of the standard, they are all 128-bit block ciphers, and they all support 128 and 256 bit keys.

Digital Signature Algorithms

Digital signature algorithms were discussed earlier; they provide a way to combine public key encryption and cryptographic checksums so that a piece of information is attached to a specific identity:

Rivest, Shamir, and Adleman (RSA)

See the discussion earlier in the Section 3.5.1 section.

Digital Signature Algorithm (DSA) and the Digital Signature Standard (DSS)

The DSA is a public key algorithm that can be used to generate digital signatures. The key size is between 512 and 1024 bits (in 64-bit increments). A key size of 512 bits is too small for long-term security, but 1024 is acceptable.

The DSS is a U.S. NIST standard, issued in 1994, that standardizes the use of DSA; in an official sense, the DSA and the DSS are separate objects (one of them is an algorithm, and the other is an official U.S. government document), but in practice, the terms are often used interchangeably. The DSA is between 10 and 40 times slower to verify signatures than RSA. Some elements of the design of the DSA make it difficult to use for encryption, but it is possible with a full implementation of the algorithm.

The patent situation in regard to implementations using the DSA is unclear; there is some possibility that parts of it are patented and thus cannot be used without paying license fees. The U.S. government has indicated that they would indemnify companies that were sued by possible patent holders, but only if they were implementing the DSS as part of a government contract.

Elliptic Curve

Elliptic curve algorithms are discussed later, in the section on key exchange. They can also be used for digital signatures.

Cryptographic Hashes and Message Digests

Cryptographic hashes and message digests were discussed earlier; they are designed to take a long piece of data and generate a shorter value, in a way that makes it easy to detect changes to the long piece of data:

MD4

MD4 is a cryptographic hash algorithm that calculates a 128-bit number from an input of any length.

This algorithm was designed by Ronald Rivest and released in 1990 as RFC 1186. In 1996 some significant flaws in MD4 were discovered. As a result, MD4 should not be used.

MD5

MD5 is a cryptographic hash algorithm that calculates a 128-bit number from an input of any length.

This algorithm was designed by Ronald Rivest as an improvement to MD4 and was released in 1992 as RFC 1321. Research on MD5 has indicated that one of the design goals of a cryptographic hash (collision resistance) has been violated. A general way to generate collisions has not been found, but the research is troubling. Current cryptographic wisdom also suggests that the size of a cryptographic hash function should be at least 160 bits in size in order to be resistant to birthday[5] attacks. Given these issues, MD5 should probably be avoided in situations where long-term digital signatures are required.

SHA and SHA-1

SHA and SHA-1 are cryptographic hash algorithms that calculate a 160-bit number from an input of any length.

The SHA algorithm is a U.S. NIST standard and was first issued in 1992 for use with the DSA. In 1995 NIST released a technical update to SHA called SHA-1. This update supersedes the previous version and is thought to address a collision problem similar to the one discussed previously in MD5. SHA-1 should now be used instead of SHA. As this algorithm calculates a 160-bit value, it is more resistant to birthday attacks.

HMAC

HMAC is a method for combining a cryptographic hash algorithm with a key. It will work with any cryptographic hash that produces at least 128 bits of output. HMAC is described in RFC 2104.

Key Exchange

Key exchange algorithms are used to allow two parties to agree on a shared secret across an unsecured network. They are occasionally more correctly called key agreement algorithms:

Diffie-Hellman

Diffie-Hellman is a key exchange algorithm that can use varying key sizes (theoretically unlimited).

This algorithm was invented by Whitfield Diffie and Martin Hellman in 1976. It uses exponentiation and modular arithmetic as the basis of its calculations; this is known to be secure, but it involves very large numbers and relatively slow calculations. One of the most important features of Diffie-Hellman is that it can be used to generate a secret that has perfect forward secrecy. Diffie-Hellman was patented, but the patent expired in 1997 so the algorithm can now be freely used.

Diffie-Hellman is a pure key exchange algorithm, which cannot be used to encrypt data. People who claim to be using Diffie-Hellman to encrypt data are extremely confused (unfortunately, because Diffie-Hellman is commonly used for key exchange with bulk encryption schemes, such people are not as rare as one would hope).

Elliptic Curve

A new class of algorithms, called elliptic curve algorithms, is based on the mathematics of polynomial equations. (Ellipses are related to elliptic curve algorithms extremely indirectly; elliptic curves use the kinds of polynomials that are also used to calculate facts about ellipses.) Elliptic curve cryptography uses very simple calculations and very complex mathematics (unlike Diffie-Hellman, which uses complicated calculations and elegant mathematics), and the resulting keys are faster to generate and smaller than Diffie-Hellman keys at the same apparent level of security.

Elliptic key algorithms are much newer than Diffie-Hellman, which gives them two significant drawbacks. First, the mathematical foundations, including the cryptographic strengths and weaknesses, are not as well understood. Second, elliptic key algorithms are still subject to patent protection (and there are significant arguments about who owns what patents). As of this writing, elliptic curve algorithms are still considered a relatively risky choice; this may change as more mathematical results are found (it is beginning to look as if they may become a widely accepted choice, but it is also possible that they will become unusable, if there turns out to be a general solution to the problem that makes them difficult to solve).

RSA

RSA, the all-purpose cryptographic algorithm, can also be used for key exchange. Like Diffie-Hellman, it is secure but slow and memory-intensive for this purpose.

Key Sizes and Strength

Table 3.1 gives our recommendations for acceptable algorithm types and key lengths. This sort of information is volatile; weaknesses are continually being discovered in algorithms; new algorithms are being developed; and both the speed and memory capacity of computers is increasing all the time. However, these are what we were willing to use at the time this book was published. We don’t think it will ever be a good idea to use these algorithms with shorter keys than those shown.

Table C.1. Acceptable Cryptographic Algorithim and Key Lengths

Purpose

Size (in bits)

Acceptable Algorithms

Symmetric encryption

128

IDEA
Blowfish
RC4

Symmetric encryption

112

3DES

Cryptographic hashes

160

SHA-1

Cryptographic hashes

128

MD5

Key exchange

1400

Diffie-Hellman

Key exchange

1024

RSA

Digital signatures

1024

RSA
DSS

Evaluating Other Algorithms

Evaluating the strength of a cryptographic algorithm can be extremely difficult. It’s not unusual for people to find problems with algorithms that have been examined before by multiple professional cryptographers. However, this sort of analysis is needed only for new cryptographic algorithms. In general, a reasonably educated and suspicious person can do an adequate job of figuring out whether a cryptographic product is appropriately secure without delving into any of the details of the algorithms involved. A good resource is the “Snake Oil FAQ”, published regularly on the sci.crypt newsgroup.

In fact, in most cases, all you need is the suspicion. Cryptography is a difficult business: it’s hard to come up with good cryptographic algorithms; there are trade-offs between the speed of an algorithm, the memory requirements of an algorithm, and the strength of an algorithm; and no algorithm is perfectly unbreakable. Therefore, any product that advertises a magic new algorithm that runs really fast on small devices and can never be broken is at best over-optimistic and at worst fraudulent.

If you need to evaluate an algorithm, here are some questions you should ask:

  • Has the algorithm been published? If not, has it been independently evaluated by multiple professional cryptographers? Independent evaluation is absolutely required to be sure that an algorithm is strong (algorithms are like arguments; everybody finds their own unassailable). Furthermore, a strong algorithm is not weakened by being made public. You should be suspicious of unpublished algorithms, and you should not accept algorithms unless there are independent evaluations of them.

  • Is the algorithm being used for its intended purpose? It is possible to use hashing algorithms for encryption, and vice versa, but most algorithms work best when used for what they were designed.

  • Is the algorithm being used exactly as designed? Apparently small changes in algorithms (optimizations in how values are calculated, changes in constants, differences in the values used to pad out odd-sized values to the block size needed for block-mode algorithms) can make big changes in the security of the algorithm. All such changes need independent evaluation.

  • Are the key sizes being used acceptable? As we’ve discussed, key sizes mean different things to different algorithms. This makes it hard to decide what key length is long enough. On the other hand, you can often identify cases where a key is too short. It is extremely improbable that a 40-bit key, or even a 56-bit key, will ever again be long enough to protect data with a useful lifetime of more than a day. Present-day symmetric algorithms make maximum use of the available key length, and there is no such algorithm that will hold out against a determined attacker for more than a day with a 56-bit or shorter key.

  • How new is the technology? It takes several years to develop enough experience with new techniques to give cryptographers confidence in them.

If you can get good answers to these questions, the algorithms are probably acceptable for most purposes. If you are trying to conceal highly important secrets, you may want to hire a cryptographer to do the analysis for you.

Meanwhile, good luck with your firewall.



[1] HMAC, although it is capitalized like an acronym, does not have an official expansion in the standard. In the paper originally describing the algorithm, it stood for “Hash-based Message Authentication Code”.

[2] RFC 1750 is an excellent source of information about random numbers for use in security applications.

[3] This is true only because good color photocopiers are not in widespread use in offices.

[4] See the book Cracking DES: Secrets of Encryption Research, Wiretap Politics and Chip Design, by the Electronic Frontier Foundation (O’Reilly & Associates, 1998).

[5] A birthday attack is based on probability and is related to the question: How many people have to be in a room for there to be two people with the same birthday? The surprising answer to this is that there is more than a 50 percent chance of having two people with the same birthday if there are at least 23 people in the room. This footnote is too small to contain an explanation, but we encourage you to look this up in any good book on probability.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.30.253