SSL is an excellent protocol. Like many tools, it is effective if you know how to use it well, but it is also easy to misuse. If you are deploying SSL, there are many pitfalls to be aware of, but with a little work, most can be avoided. In this article, we discuss the seven most common pitfalls when deploying SSL-enabled applications with OpenSSL.
A common complaint about SSL (and its successor, TLS) is that it's slow. Yes, it's a lot slower than a traditional, unsecured TCP/IP connection. However, any inefficiencies that exist with SSL are a direct result of it providing adequate security. Nonetheless, this problem leads many people to avoid using SSL altogether.
Most of the inefficiencies in SSL occur at connection establishment. The actual encrypted data exchange isn't noticeably slow. Therefore, if your applications don't need to make more than a few dozen new connections per second, you shouldn't be worried about efficiency with SSL.
There are ways to boost the speed of SSL. One way is to use session caching, which removes the most expensive part of the connection process for those clients who have previously connected. Another way is to purchase cryptographic-acceleration hardware. OpenSSL supports most such hardware. Finally, it's possible to offload SSL connections to multiple machines using load balancing.
In a typical SSL installation, the server maintains credentials so that clients can authenticate the server. In addition to presenting a certificate at connection time, the server also maintains a private key, which is necessary for establishing that the server presenting a certificate is actually presenting its own certificate.
That private key needs to live somewhere on the server, and needs to be protected from prying eyes. If an attacker breaks into a machine, stealing the key could allow them to impersonate the server, so regular file permissions may not be enough. Cryptographic-acceleration cards will generally store the key in hardware, making it unavailable to the actual computer.
If such an option isn't feasible, then you can either leave the key unencrypted on disk, or encrypt it using a passphrase, which needs to be typed in at program startup. The former solution makes an attacker's job easier, but at least the program can start up unattended.
If a server's private key does manage to get stolen, it can often be used to decrypt all past communication with the server, assuming the previous communication was recorded. The solution to this problem is to use SSL's facility for ephemeral keying. With ephemeral keying, a temporary key pair is generated when you create a new SSL session. This is then used for key exchange, and is subsequently destroyed. By using ephemeral keying, it is possible to achieve forward secrecy, meaning that, if a session-specific key is compromised, messages encrypted with previous session keys will not also be compromised.
A server's private key can be stolen. Additionally, certificates sometimes go into circulation that are fraudulent. For example, in early 2001, there were two certificates floating around that were purported to belong to Microsoft, when in reality, they did not.
SSL has a mechanism for thwarting these problems: Certificate Revocation Lists (CRL). Once the Certification Authority (such as VeriSign) learns that a certificate has been stolen or is otherwise invalid, the Certification Authority adds the certificate's serial number to a CRL. The client can access CRLs and validate them using the Certificate Authority's certificate.
Not using CRLs leaves an application open to serious vulnerability. However, CRLs don't completely solve the problem. The biggest problem with CRLs is that it can take time for an organization to realize that a key is stolen and to notify the Certification Authority. Then the CRL needs to be published, and it needs to make its way to the client. All of this can take a long time, and until it's all completed, exploitation is possible. There are other issues with deploying CRLs. See our book Network Security with OpenSSL for more information on CRLs.
CRLs aren't useful if the client software isn't first adequately validating the server certificate. Certainly, for SSL to work at all, the client must be able to extract the public key from a presented certificate, and the server must have a private key that corresponds with that public key. But, without certificate checking, there is nothing to verify that the client has the right public key, meaning that it could be talking to a "man-in-the-middle" instead of the server.
In order to perform adequate certificate validation, the client must have an implicit notion of the minimal set of certificates that should be considered valid, and must be able to check whether a presented certificate is in that set.
A common solution is to trust everything signed by a particular Certification Authority. However, anyone can get a certificate signed by any Certification Authority, and often under false pretenses. If you rely on the authority for authentication, you're likely vulnerable to man-in-the-middle attacks. Another solution is to use a hard-coded list of valid certificates. Unfortunately, this solution doesn't scale well as a system grows.
A more solid approach is to only accept a subset of certificates signed by a particular Certification Authority. Digital certificates have a wealth of information in them, such as the entity that is associated with the certificate, and a DNS name associated with that entity. The Certification Authority signs that information, so as long as the authority's signature is valid, the information should be a reasonable differentiator.
Another approach is to run your own Certification Authority. That's a lot of work, and not recommended for most people. However, we discuss the tools you need in order to do this in the book Network Security with OpenSSL.
In the SSL protocol, both the client and the server need to generate random data for keys and other secrets. The data must be generated in such a way that a knowledgeable attacker cannot guess anything about it. Numbers produced from traditional pseudo-random number generators are not sufficient for security. OpenSSL does have its own cryptographic pseudo-random number generator, but it only provides security if it has been "seeded" with enough random information.
A seed is a piece of data fed to the generator to get it going. Given a single, known seed at startup, the generator will produce a stream of predictable outputs. The seed itself must be a random number, but it needs to be a truly unguessable piece of data of sufficient length to thwart any possible guessing attacks. Usually, you'll need at least 128 bits of data, where each bit is just as likely a 0 as it is a 1.
If you try to use OpenSSL without seeding the random number generator, the library will complain. However, the library has no real way to know whether the seed you give it contains enough entropy. Therefore, you must have some idea of how to get entropy. There are hardware devices that do a good job of collecting it, including most of the cryptographic accelerator cards. However, in many cases hardware is impractical because your software will be deployed across a large number of clients, most of which will have no access to such devices.
Many Unix-based operating systems now come with a random device that provides entropy harvested by the operating system. On other Unix systems and on Windows NT systems, you can use tools such as EGADS, which is a portable entropy collection system.
While version 3 of the SSL protocol and TLS are believed to be reasonably secure if used properly, SSLv2 (version 2) had fundamental design problems that led to wide-ranging changes in subsequent versions (version 1 was never publicly deployed). For this reason, you should not support version 2 of the protocol. This ensures that an attacker does not launch a network attack and cause the client and server to settle upon the insecure version of the protocol. This is easy to do by intercepting the connection request and sending a response that makes it look like a v3 server does not exist. The client will then try to connect using version 2 of the protocol.
Additionally, you should avoid small key lengths and, to a lesser degree, algorithms that aren't well regarded. Forty-bit keys are never secure and neither is 56-bit DES. Nonetheless, it's common to see servers that only support these weak keys due to old U.S. export regulations that no longer apply.
As for an individual algorithm choice in SSL, RC4 and 3DES are both excellent solutions. RC4 is much faster, and 3DES is more conservative. Soon, TLS will be standardizing on AES, at which time TLS will be widely regarded as a good choice.
John Viega, Matt Messier, Pravir Chandra is CTO of the SaaS Business Unit at McAfee and the author of many security books, including Building Secure Software (Addison-Wesley), Network Security with OpenSSL (O'Reilly), and the forthcoming Myths of Security (O'Reilly).
O'Reilly & Associates recently released (June 2002) Network Security with OpenSSL.
Sample Chapter 1, Introduction, is available free online in PDF format.
For more information, or to order the book, click here.
Copyright © 2009 O'Reilly Media, Inc.