> We do not have time to explain public key cryptography right now, but this is basically the encryption key we’re going to use to talk secretly.
If there's one misunderstanding that it'd be valuable to clean up about protocols like TLS in 2020 this would be it.
It is technically possible to do this. It's how PGP worked for example, and it was how SSL was originally conceived, but it is not now commonly used and is unsupported entirely in TLS 1.3
Let's take my connection to send this message to Hacker News. It's not TLS 1.3, but the previous version TLS 1.2 instead, and it has a 2048-bit RSA public key in the certificate. Is this key used "to talk secretly" ? No!
Instead my browser and HN's server use a variant of the Ephemeral Diffie-Hellman protocol with Elliptic Curves to pick a completely random key and that key is used "to talk secretly". The public RSA key's role is only to prove that I am communicating with Hacker News and not somebody else pretending to be them. That's all it is for on modern sites talking to modern browsers.
This is what Forward Secrecy is all about. Since the keys used to secure messages were not based on that fixed long term RSA key, but instead a random key both parties soon forgot about, we achieve Forward Secrecy as neither of us can (whether by mistake or on purpose) later reveal how to decrypt the messages.
To be fair, the focus of the article was an introduction to TLS certs, what's in them, and how they're used. There's a lot of complexity, confusion and jargon in this topic and Julia made a good call not go into the rabbit hole of public key encryption. Perhaps it would have been better to just say the RSA key "is used as part of the process" of encrypting traffic between browser and server.
It's also possibly to use an out of band transmitted pre-shared key with TLS, see eg this Python module that exposes OpenSSL's support for the TLS PSK feature to Python: https://github.com/drbild/sslpsk.
That depends on your cipher selection, IIRC. At a previous job, we had an appliance that got a mirror port of our uplink and could record HTTP sessions between customers and our webapps; it was given a copy of the private key, and it worked great, right up until newer HTTPS standards pushed PFS and broke it.
It is still technically possible to do RSA key exchange. About 2% of sites surveyed for SSL Labs "Pulse" don't offer anything better. Current browsers will (reluctantly) accept that you only speak RSA.
But it's a terrible idea. If your employer purchased that appliance believing it was anything other than a temporary stopgap they were incompetent and/or the appliance was mis-sold.
The right way to build such an appliance records the session keys. The growing pile of keys is a constant reminder (in a way that a copy of one RSA private key is not) that this is valuable/ dangerous private information which you should have a habit of routinely destroying once it's not operationally vital.
Yeah the appliance was old and painful to work with at the best of times. We actually managed to remove it when it broke and we couldn't figure out to fix it:) Ended up replacing it with gathering stats on the actual application servers, which was so much better (better even than recording keys, because the app sees traffic without any encryption in the way).
EDIT: I guess my original point was that, while it's not a good idea, at least as of early 2019 it was possible to do the old-style encryption.
A question I'm facing with SSL that wasn't satisfied by the article:
What SSL vendor has the shortest certificate chain?
I'm looking to optimize SSL handshakes and outbound traffic in general from Cronitor's telemetry API and shrinking that certificate chain will make a big impact, but I couldn't find a comparison between vendors. I did some sampling, downloading cert chains, but it was far from exhaustive.
Down to the byte level, I'm not sure, but if you can get an all ECC chain (or as much ECC as you can get, gorkish points out below that all ECC isn't practical), those certs are gobs shorter than RSA certs, because the public keys are shorter.
Otherwise, any CA that's been around for long enough should be able to give you a cert signed by an intermediate signed by their trusted root; so you would just send clients your cert and the single intermediate cert.
You should only have a chain longer than two certs if you need to cross chain to another root; but so many of the older clients that needed really old CAs were forced off of PKI because they don't support SHA256 signatures.
Getting an all-ECC chain EV cert that is published to the CT logs is dang near impossible. I spent a couple of months of back and forth with DigiCert over the last 2.5 years or so trying to get one, but they were never able to issue one despite trying and having the correct roots and intermediates in place to do this. I feel this is one of those situations where their software simply couldn't handle this edge case, and I was not important enough to escalate to a manual process.
The benefit to an all ECC chain (including an ECC root) is not just size. There is a some small amount of time and energy especially on mobile devices on first load when validating ECC signatures compared to RSA 4096 signatures of the intermediate and client cert (the signatures are bigger too). Granted, it is cached after that, but collectively if I have 10 million sessions per month that's real time and energy wasted.
A quick check on ssl labs says a site I'm familiar with sends 2717 bytes of certificate matter with an ECC entity certifcate, and 2921 bytes with an RSA entity certificate. The intermediate is the same for either chain, and it doesn't send the root.
204 bytes is not that much, and I'd have to run packet captures to check how much other data is going into a TLS handshake, but that seems like it is going to be throwing an extra packet in for some people, depending on their effective MSS. This particular certificate has 7 Subject Altnerative Names, the difference for a smaller certificate would be a larger portion of the handshake data.
So, just because I'm more familiar with DigiCert, and it's more clear with specific names.
Let's say you had a certificate for CN=example.org, issued by DigiCert ECC Secure Server CA, the certificate of which is itself is issued by DigiCert Global Root CA
Most clients have that CA in their chain, so you can send the example.org cert, and the DigiCert ECC Secure Server CA cert, and have very good compatibility. DigiCert Global Root CA was created November 2006, and maybe your client has a CA bundle from before then, or anyway doesn't have that CA. Not to worry, DigiCert has a cross signed copy of DigiCert GLobal Root CA, issued by Baltimore CyberTrust Root. Baltimore CyberTrust Root was created in May 2000, and most people like them.
So, to support that small fraction of users which have Baltimore CyberTrust Root and not Digicert Global Root CA, you can send
CN=example.org, the normal DigiCert ECC Secure Server CA, and the cross signed Digicert Global Root CA, issued by Baltimore CyberTrust Root.
Now, DigiCert happens to own the CA key for Baltimore CyberTrust Root, so they also can issue certs from a new intermediate they generated signed by it, but they were using their cross-signed Root as an option for compatibility with legacy clients before they purchased the CA. Sending the three certs should also work for well behaved clients that have the DigiCert Global Root CA, but not Baltimore CyberTrust Root; although not all clients will properly validate when they trust a CA in the chain, but not the last CA in the chain.
I'm not affiliated with DigiCert, I was worked for a customer, and was in charge of selecting the CA while we supported a lot of ancient phones, each with their own mess of CA bundles, very few of which were documented. :(
If you set up a new CA, you're not immediately in browser roots until you can prove you're running your CA in a responsible fashion. It's usually easier to pay an existing CA to sign your root cert as if it was one of their own intermediates, and follow their rules to get established before tackling getting approval in browsers. Even after you're approved, you need to wait for users to upgrade to new browsers/OSes/devices (depending on use case) to have your cert included in their trust store.
This even applies if you are the browser vendors, Lets Encrypt was cross signed for the first year or so of its existence.
Not an expert, but I've assumed as long as the certificate(s) fit in a TCP packet the precise size doesn't matter too much. Your certificate + intermediary + root (3 total) seems reasonable.
A related thing to look into, if you are not using it already, is ECDSA certificates. They are a little smaller than RSA, but, more importantly, they are easier on the CPU -- more handshakes per second.
Hey Peteris, thank you for the reply, hope things are well.
One thing we found is that sometimes clients on a VPN have a smaller max packet size, causing SSL connections to fail, but it's not a main thing we're trying to solve. Primarily it's bandwidth and speed.
> sometimes clients on a VPN have a smaller max packet size
This sounds like a path MTU problem. There's a couple ways to solve this.
-1) Make sure you're not dropping icmp needs frag packets.
0) Ignore it --- it's not really your problem, and it's 2020, people shouldn't screw up MTU like it's 1997 anymore. This is easy, but not very effective.
1) clamp your outgoing MTU to 1480. A lot of big sites do this, and it avoids problems in most of the broken networks, but you're adding overhead. But it's pretty easy to do. Doing it so you send lower MSS back to the client helps with large packets they send you.
2) Clamp effective MTU to whatever the other side told you in the TCP SYN - 20 (or whatever value you like). This isn't easy, but it fixes a lot more networks.
3) Like 2, but targetted to only networks were you detect path issues. This would be a lot of work, but very effective. (I haven't been able to convince people to do this, but I've seen packet traces that show it would work). You could also try to reach out to the most broken networks, and change the world for the better.
4) Your OS almost certainly has path MTU blackhole detection, but it might not be enabled, or it might not be very fast acting. Check if you can enable it with a fast timeout.
(To the thread; sorry, this isn't related to the article at all)
It depends on what you want to support. Browsers for example have been adding intermediates to their cert stores, so if you only want to support known new browsers, you only need to send the server certificate and nothing else...assuming said intermediate signed is one of the certs the browser has supplied.
If you care about performance then you should start by reading High Performance
Browser Networking (the text is available online here https://hpbn.co/ ).
Nice post, good for a certain degree of "dissecting".
I assumed however that we'd be going all the way down to the bytes. I spent quite a long time with "A Layman's Guide to a Subset of ASN.1, BER, and DER" as a close companion, though it looks like letsencrypt has created a friendlier intro: https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/
While it's relatively rare that you'll have to understand the encoding, it can be a lifesaver to have that skill if you're looking at some raw dump of of a cert (or other BER/DER encoded data).
I had a co-worker once who was famed for having a BER/DER decoder in his head. He'd look at a hex dump and point to a spot somewhere in the middle and declare something like "there's your problem: the cert signing bit isn't set in your key usage extension".
Setting up a wildcard search for your domains with crt.sh's rss feeds into slack is a great way to stay alerted on certificates issued on your domains.
The logs are publicly accessible services, here is Google's information on logs they trust (e.g. in Chrome) and you can find equivalent information for Apple (for Safari)
But, a CT log is a very high availability service, designed to present a very narrowly defined API (RFC 6962) to the world, it is not tailored to be user friendly.
A sibling post mentions crt.sh, which is a web site (and associated services including a Postgres) that consumes the data from the logs. If you're curious and just want to poke around, maybe satisfy yourself that your own certificate is indeed logged you should play with https://crt.sh/
If there's one misunderstanding that it'd be valuable to clean up about protocols like TLS in 2020 this would be it.
It is technically possible to do this. It's how PGP worked for example, and it was how SSL was originally conceived, but it is not now commonly used and is unsupported entirely in TLS 1.3
Let's take my connection to send this message to Hacker News. It's not TLS 1.3, but the previous version TLS 1.2 instead, and it has a 2048-bit RSA public key in the certificate. Is this key used "to talk secretly" ? No!
Instead my browser and HN's server use a variant of the Ephemeral Diffie-Hellman protocol with Elliptic Curves to pick a completely random key and that key is used "to talk secretly". The public RSA key's role is only to prove that I am communicating with Hacker News and not somebody else pretending to be them. That's all it is for on modern sites talking to modern browsers.
This is what Forward Secrecy is all about. Since the keys used to secure messages were not based on that fixed long term RSA key, but instead a random key both parties soon forgot about, we achieve Forward Secrecy as neither of us can (whether by mistake or on purpose) later reveal how to decrypt the messages.