PKI: Broken, But Fixable
- Identity or Encryption? / Who Does the Signing?
- Certificate Revocation / Who Do You Trust?
- Disagreements / DNSSEC for Key Distribution
Over the past few months, we've heard about new compromises at certificate authorities (CAs) that seem to allow anyone to pretend to be your bank. How did this happen? On the Internet, Transport Layer Security (TLS) and the public key infrastructure (PKI) model are the standards for encryption. Are they really as broken as this news would imply?
Identity or Encryption?
If you've ever set up an encrypted server, the first thing you probably did was test it with a self-signed certificate. If you use a web server with a self-signed certificate for HTTPS, your browser will give you a scary warning. At first glance, this seems wrong-especially since the browser doesn't give you a warning when you go to a site that isn't using encryption at all.
The reason is quite simple. Encryption and identity are very closely related. Imagine that you have two teletype machines connected to each other by a completely secure link. Anything typed on one end appears on the other end. Now place both of the machines in public places, and arrange for a friend to use one of the machines to communicate with you. When you arrive at your terminal, someone starts typing. How do you know that your friend is originating the message, rather than someone else who just happened to walk up?
Modern encryption protocols let you establish a connection that, if not 100% secure (if such a thing is even possible), is sufficiently hard to crack that it's generally not worthwhile to do so. When you connect to your bank, you can assume that the connection is secure. Similarly, when you connect to a site with a self-signed certificate, you can be fairly certain that no one is eavesdropping. However, you can't be certain that the person at the far end is really who you expect.
At the moment, Domain Name System Security Extensions (DNSSEC) isn't widely deployed. When you connect to a remote server, you typically do so by entering a host name. Your computer turns the host name into an IP address using a completely insecure protocol. If you're on a WiFi network, for example, it's trivial for someone else on the same network to return a fake result to you. When you connect to "my.trusted.bank.com," you'll actually be connecting to that person's laptop. Then you establish a completely secure connection to that unintended recipient, who in turn might establish a completely secure connection to your bank-and intercept (or even modify) all of your traffic.
The point of the signature is to give a bit more support to a recipient's claim that it's really your bank. This is why browsers warn you if you visit a site with a self-signed certificate: If you visit your bank online and get a secure connection with a self-signed certificate, you want to be informed that it probably really isn't your bank.
Who Does the Signing?
Hopefully you'll agree that it's important to have some assurance that the remote party is really who you think it is. The next question is how to do this. Unfortunately, that's where the system starts to have problems.
Every browser (or, in some cases, operating system) comes with a list of certificate authorities that it trusts. These CAs are allowed to sign any certificate, and it will be treated as valid.
There are a few problems with this system. The first is that there's no restriction on which domains a CA can sign. For example, a CA in the People's Republic of China can sign a .gov.uk domain, and a CA in France can sign a U.S. .gov domain. Your browser will trust them equally. This makes it very easy for governments to perform attacks on SSL connections. There have been reports of U.S.-based registrars being, uh, encouraged to sign certificates for the U.S. intelligence services, and it would be naïve to imagine that the same practice doesn't go on in other countries.
To make matters more fun, certificates can include wildcards, which is quite useful. For example, http://www.informit.com can share a *.informit.com certificate with any other subdomains. Unfortunately, this also means that a CA can sign a certificate for *.com, and it can then be used for any .com domain. Worse, you can even get a wildcard certificate that's valid for any domain.
There's no way for a browser to check whether a certificate was created by someone who is authorized to create a certificate for that domain. There was a story a few months ago about a group of researchers who managed to get certificates signed for microsoft.com and a few other domains. Generating a certificate is trivial (anyone with OpenSSL installed can do it in a few seconds), but it doesn't become useful until it's signed by a trusted third party. Apparently this step is also very easy, though.