Secure Socket Layer, otherwise known as TLS (Transport Layer Security) keeps the internet safe. I’ll use the two acronyms interchangeably, despite TLS being the correct one.
If you’ve ever heard someone say, “don’t give sensitive information unless you see the green lock in the address bar”, you’ve used (and been instructed to use) SSL. If you’re using SSL, your address bar should say
TLS/SSL facilitates an encrypted connection between a given client and a participating server. Let’s say I host and run a dating website. Technically speaking, this means I run a web server on a computer somewhere, connected to the internet. This web server runs on port 80.
You are a member of my dating website - you’re updating your profile while sitting at a Starbucks, chilling on public WiFi. Since the (TCP) connection between your web browser and my web server is not encrypted, all information flowing back and forth over the internet is sent, transmitted, and delivered in plaintext. Any mischievous teenager sitting in your Starbucks can monitor the invisible packets hurtling through the air towards the coffee shop’s router - and he or she can read all about how you love long walks on the beach. Worse still, he/she can intercept the packets going from you to the router, change the information, then send them off to my dating site! The attacker can also just pretend to be the website, and never send the packets off to the router at all.
Since I (should) care about my users’ privacy, I can fix this problem. I obtain an SSL certificate, and host that on my web server. Now, if a client connects to my web server on port 443, the connection should be end-to-end encrypted, meaning only the client and I can read its contents.
How does it work?
An SSL certificate is really (like everything transmitted on the internet) a blob of text. Only a few parts of this blob are germane here – but the main takeaway is the certificate contains a public key. I generate a key-pair (public and private key). When you connect to my dating site, I send you a public key. You can now send me a message, encrypted with said public key. The only person that can decrypt the message is the owner of the private key that pairs up with that public key. If you send me your own public key, I can send you a message that only you can decrypt.
(I’m glossing over, significantly, the details of this handshake. Suffice it to say that the server and client exchange public keys that allow them to send secret messages to each other.)
Great! I can send you messages that only you can read, and you can do the same to me. Our Starbucks hacker has been foiled.
But wait - there’s still an issue.
What’s to stop Starbucks hacker from intercepting your connection to my dating site (AKA man-in-the-middle) and simply providing his/her own public key? In that case, the connection would be encrypted between you <-> hacker, and he/she could pose as my dating site…
There’s a fundamental issue with the internet, here. When you send out a request to say, Google, you can make no confident assertions about the integrity, authenticity, or secrecy of what you’ve received. Packets can be read, modified, corrupted, destroyed, reordered, and more along the way.
We need a way to prove to ourselves that a request using SSL to Google actually went to the entity that owns
google.com, and came back to me, untouched.
Imagine a connection as a telephone line between client and server. How can we confirm that we’re really talking to the person that owns
We don’t trust
google.com, just now. What if someone we did trust informed us that the certificate
google.com is trustworthy?
An intermediate party can sign
google.com’s certificate and say: “hey, trust me, this cert is legit. This public key is definitely being served by the real owners of the website.” (This is a cryptographic signature)
But how can we trust them? Well, shit - this will never end. How can we trust anyone?
If you’re looking for an elegant solution here you won’t find one. The world has agreed upon a set of root Certificate Authorities (organizations that prove website ownership and distribute SSL certificates to those that do) that we trust unconditionally.
Often what happens is
google.com’s certificate has been signed by an intermediate, who in turn has their certificate signed by a root certificate.
These root certificates are often distributed to clients via out-of-band solutions: such as being built directly into browsers or even shipped by computer manufacturers.
So when you connect to my dating site: I provide you with a certificate that claims I own this website. I also provide you with an intermediary certificate and a signature from the intermediary verifying the authenticity of my certificate. Finally, I provide you with you a root certificate (which you can verify yourself, since you have the key in your browser already) and a signature from the root verifying that the intermediate certificate is legit.
Certificate authorities (those that own root certs) have this authority because they’re the ones who distribute certs. If you go to GoDaddy and host your website with them, if you prove to them (through their own methods) that you own your website, they’ll provide you with and sign your certificate (or an intermediary, who will then do the same for you).
A more devious reader asks: what happens when the any of the servers in the chain get hacked? What happens if an attacker steals the private keys that essentially unlock the entire SSL certificate?
So far we are safe from our Starbucks hacker. He can’t send his own certificate (public key) when you connect to my dating site, since his certificate hasn’t been (eventually, through the chain) been signed by a root CA. Your browser won’t trust this certificate, since it can’t verify that the certificate was issued by someone we trust.
But… I have control over my certificate as long as I have my private key (since my private key is the only non-public part of my certificate). If the Starbucks hacker managed to exploit a vulnerability on my server and gained access, he or she could steal my private key!
Once the hacker does this, they can man-in-the-middle attack you again. They can intercept the connection, send my certificate (which your browser thinks is legit), and decrypt all messages coming from the dating site to your computer. They can also simply pose as the server and trick you into sending sensitive information.
What’s a secure webmaster to do?
Things like this have happened. Heard of heartbleed? Heartbleed allowed anyone to potentially view sensitive information on the server. If you hosted a website that served SSL certificates when heartbleed occurred, you revoked your certificate, because there was a risk your private key was compromised.
This basically amounts to calling up your Certificate Authority and saying, “hey… I lost my cert. Can you let the world now they should not accept that certificate anymore? Oh, and can you give me a new one?”
Now you serve a new, totally different certificate. But there’s potentially a hacker out there with your old certificate and private key, waiting to man-in-the-middle unsuspecting latte drinkers.
If you are visiting my dating site, you might be sure that the certificate is valid, but how can you be sure that the certificate isn’t revoked and thus hasn’t been compromised?
You as a client have a few options:
Certificate Revocation Lists: or CRLs, are lists provided by Certificate Authorities (the companies everyone apologizes to) that contain all revoked certificates they control. All certificates (which are immutable, by the way) contain a link to their appropriate CRL. When browsers visit Google, they can check the CRL and see if the cert they’ve been served is on the list (is revoked). If it is, they should proceed with caution (leave). Unfortunately CRLs can reach the megabyte magnitude – can you imagine if a simple request to
google.comtriggered a 60MB download? There are ways to cache these CRLs, but it’s not perfect.
Online Certificate Status Protocol: or OCSP, is a mechanism aimed to reduce the load induced by CRLs. All certificates that support OCSP have a link to an OCSP endpoint – clients can hit this URL and say “has this certificate been revoked?” Rather than getting a huge list of revoked certs, OCSP lets clients ask specific questions about the site they’re visiting. This is, of course, a privacy issue - CAs know exactly what websites you’re visiting. Also - you’re still making two web requests for the price of one - that latency is precious.
OCSP Stapling: This is pretty clever. Rather than you as the client making the OCSP request, the server does the following: the server attaches “I AM USING OCSP STAPLING” to the certificate (immutable, remember). The server then makes an OCSP request to the endpoint saying, “has my certificate been revoked?” – the server ‘staples’ this response to the certificate, and sends it to the client. The client sees “I AM USING OCSP STAPLING”, knows that certificates can’t be changed, the keys can just be stolen, and so knows the cert must include an OCSP response. If it doesn’t have one, then it rejects the cert as invalid. If the certificate has been revoked, the hacker has to inform the client that he’s serving a revoked certificate!
They all have their issues - OCSP stapling seems perfect but something like 8% of all servers support it - since the burden is on servers, there’s not much anyone can do.
Assuming it all works fine (it doesn’t), you could ensure that the certificate being served to you (potentially by Starbucks hacker) hasn’t been revoked, and thus is valid.
This is a quick & dirty intro to SSL. SSL works reasonably well, despite some flaws in browser support and sysadmin due diligence. This is a precursor to some future posts that dig down into the details of a few things mentioned here, and some of my personal research that deals with improving the revocation situation.
PS: What happens when a Certificate Authority’s private keys are stolen? It means the hacker can issue any certificate, to ANY website he desires. Basically, we’re screwed. This has happened.