When people ask me something technical, I frequently find it useful to tell the basics as a story or an analogy. Obviously all these stories have limitations to how accurate they can get, but it’s surprising how well it gets people to understand what you mean. So this post is part of a series of “explaining technology as a story”
One of the challenges, on the internet, is to know who you are talking to. If you’re about to enter your credit card details to Amazon then you want to be sure you’re talking to Amazon, and not someone pretending to be. Similarly if you want to login to your bank you need to be sure you’re really talking to your bank.
We also want to be sure no one is listening in; TLS handles both of this but I’m only concerned around the identity aspects.
This isn’t a new problem and different solutions have been used over the years. Letters would be sealed with molten wax and stamped with a signet ring. As long as the letter was still sealed and the recipient recognized the impression in the wax then there was a level of confidence that the letter was authenticate. Well… unless the ring was stolen, or had been duplicated, or some real clever person was able to open and reseal the letter with no evidence of tampering.
On the Internet, a TLS certificate does the same thing. Instead of a wax seal impressed with a signet ring we have a cryptographic signature.
What is identity?
Identity means different things to different people…or computers.
At one level it could be “I have gone to sweharris.org… am I looking at that site?“. This is the lowest level of identity. It doesn’t tell you anything about who is operating the web site. It’s really meant for the assurance that the site that came back was the site you requested. It won’t help you if you typed the wrong name, or clicked on a link that looked right but isn’t.
“Hi, I’m sweharris.org and here’s my signature that proves it”
If this part doesn’t match then the browser will throw up a nasty warning message to try and protect you.
At another layer it could help identity the person or company or runs the website. This is meant to be for the human using the web browser to be sure that when you go to a site you have a level of trust that you know who is running it
“Hi, I’m sweharris.org, which is run by Stephen Harris and here’s my signature that proves it”
The browser can’t help so much with the “organisation” part of this; that’s for the human to verify. It’s not clear this is a big win because of how it’s normally presented to the end-user. Indeed some browsers have stopped showing this “extended” identity at all.
Both of these identities can be stored in a certificate.
Now there’s no way you can recognise all the millions of “signet rings” that would be needed. Especially when they change yearly! So, instead, we have a smaller number of people we trust, and we get them to sign it. So really what the web site sends is something closer to
“Hi, I’m sweharris.org and here’s Harry’s signature that proves it”.
We call these trusted signers “Certificate Authorities”, frequently abbreviated to CA.
That all sounds well and good, but how do you know the CA is one that can be trusted?
This is one of the harder parts. We still have hundreds of “signet rings” that can be used to create signatures. Fortunately your operating system and browser handle most of this for you. e.g. in Chrome on Linux I can go to settings/Privacy and Security/Security/Manage Certificates (chrome://settings/certificates) and then click on the “Authorities” tab). There are over 70 organisations listed there, and many of those have multiple “Root” certificates.
So now it’s something like
“Hi, I’m sweharris.org and here’s Harry’s signature that proves it, and you can check it’s a trusted signature in your CA Store”
You can think of this CA store as a book of trusted people. And you can add your own CA Roots (it’s not uncommon for enterprises to have their own internal CAs). These will work the same as a public CA for trust purposes.
And you can even add a specific certificate, so now we have
“Hi, I’m YourServer.example.org and you can trust that because you know me”
Of course it’s never that simple. For security reasons the CA Root certs are rarely used to directly sign end certificates. What really happens is that the CA creates an Intermediate certificate and this is what is used to sign the end certificate.
So now the conversation is really something like
“Hi, I’m sweharris.org and here’s Fred’s signature that proves it, and also here’s Fred’s proof of authenticity and that has been signed by Harry, and you can check Harry’s signature in your CA Store”.
This chain of trust can extend to multiple layers if necessary. It’s important that the server sends all these intermediates as a “chain” so the client can follow the chain to a trusted root.
That’s a lot of trust! Can we trust this is trustworthy?
This is where it gets a little bit messy. The main browser and CAs got together and formed the CAB Forum. This is a self-regulatory group that defined a set of rules that the CAs have to follow. If they don’t then the browsers will remove the Root CA and now the CA customers certs won’t be trusted.
Some of those rules are around how the CA verifies the customer is who they say they are. If I asked a CA for a signature claiming I was www.google.com then they should reject it because I can’t prove I own that domain.
Unfortunately with over 70 public Roots there’s a fair sized footprint for an attacker to try and get one of them to mis-sign a certificate, and some of the verification processes themselves depend on weak controls such as DNS (e.g. if I could compromise your DNS then I could create a certificate and request a signature from a CA that trusts DNS).
Since this is an “all or nothing” type scenario (“is there a chain of trust back to any Root in my CA Store?“) a compromise of one CA is pretty bad.
This is a recognized weakness of the current trust model, where ultimate trust is out of the end-user control (basically concentrated in the CABforum) and with weak processes. But it works pretty well and protects trillions of dollars per year in ecommerce globally. I think it’s good enough!
There’s a lot more to certs than just identity assertion (a lot of math for one, along with public/private keys, renewal, multiple names, wildcards, client side certs…) but I’m mostly focusing on the story around verifying the identity of a server and how a typical browser does the job.