SSL/TLS (2 Part Series)
I guess many of you know about HTTPS and some of you may have setup SSL/TLS for your web server. But how many of you understand deeply how SSL/TLS works?
Do you know:
- What really happens during a TLS handshake?
- What cryptographic algorithms are used by TLS to protect the data?
- How do client and server exchange secret keys?
- How Diffie-Hellman Ephemeral key exchange works?
- Why do we need a digital certificate?
- Why does it need to be signed by a certificate authority?
- What is a digital signature? How is it signed and verified?
- What perfect forward secrecy means?
- How AEAD, MAC, HKDF, 0-RTT works?
- What is Elliptic-Curve cryptography?
- What's new in TLS 1.3 compared to TLS 1.2?
There are a lot of questions, and I don't want to just scratch the surface. So this is gonna be a very thorough article to tell you everything about SSL/TLS, an extremely important building block of the security over the internet.
SSL stands for Secure Socket Layer. It is the predecessor of TLS.
TLS the short form of Transport Layer Security, which is a cryptographic protocol that provides secure communication over a computer network.
Here's a bit of the history of SSL and TLS:
- SSL was originally developed by Netscape, and it was first published in 1995 with version 2.0
- SSL version 1.0 was never publicly released because of some serious security flaws.
- In 1996, the SSL version 3.0 was published as a complete redesign of the protocol.
- Then 3 years later, TLS 1.0 was first defined in RFC 2246 by IETF as an upgrade of SSL Version 3.0
- It took 7 years to upgrade it to TLS 1.1 in 2006
- TLS 1.2 came right after that in 2008.
- Then finally after 10 years in the making, we got TLS 1.3 with a huge improvements in 2018.
So at the moment which SSL/TLS version still exist?
- The SSL 2.0 was deprecated in 2011
- SSL 3.0 was deprecated in 2015
- And recently, in March 2020, TLS 1.0 and TLS 1.1 was also gone. That means only TLS 1.2 and 1.3 are still active.
First, it is widely used on the web. All websites that you visit with HTTPS are secured by TLS, or we often say HTTP over TLS.
Similarly, email with SMTPS protocol is in fact SMTP and TLS.
Then FTPS for secure file transfer protocol is also FTP plus TLS.
And there are many other applications of TLS that I don’t have enough time to mention.
Because TLS gives us 3 things:
- TLS verifies the identity of the communicating parties, which normally be clients and servers.
- With the help of asymmetric cryptography, TLS makes sure that we will go to the authentic website, and not a fake one.
- TLS protects the exchanged data from unauthorized access by encrypting it with symmetric encryption algorithms.
- TLS recognizes any alteration of data during transmission by checking the message authentication code, which we will learn about in a moment.
Basically, TLS consists of 2 phases, or 2 protocols:
In this phase, the client and server will:
- Negotiate the protocol version
- Select cryptographic algorithm (or cipher suites)
- Authenticate each other by asymmetric cryptography
- Establish a shared secret key that will be used for symmetric encryption in the next phase.
So the main purpose of the handshake is for authentication and key exchange.
In this phase:
- All outgoing messages will be encrypted with the shared secret key established in the handshake.
- Then the encrypted messages are transmited to the other side.
- They will be verified to see if there’s any modification during transmission or not.
- If not, the messages will be decrypted with the same symmetric secret key.
So we will achieve both confidentiality and integrity in this record protocol.
And because the amount of encrypted data in this phase is large, this is often called bulk encryption.
Why not just use one for all purposes?
Well, it’s easy to see that symmetric cryptography can’t provide authentication. Since there’s only 1 secret key for both client and server, they know nothing about each other to verify. Not to mention that how they come up with the same key without leaking it to the public is hard.
How about asymmetric cryptography? Sounds like a good candidate. Unfortunately, it’s much slower than symmetric cryptography. And by “much”, I mean from 100 times to even 10000 times slower. So it’s clearly not suitable for bulk encryption.
Alright, now let’s learn more about symmetric cryptography. I guess you’ve already known the basics.
First of all, Alice has a plaintext message that she wants to send to Bob, but doesn’t want any one in the public zone to read it.
So she encrypts the message with a secret key that they have shared with each other before. Then she sends the encrypted message to Bob via the public internet.
Upon receiving the encrypted message, Bob will easily use the same secret key to decrypt it.
Since the same key is used for encryption and decryption, it’s kind of symmetric, so we have the name symmetric cryptography.
Now there might be a hacker Harry, who can catch their exchanged message on the public network. However, the message is already encrypted, and Harry doesn’t have the secret key, so he won’t be able to decrypt it.
But he can still change it!
There’s one technique called bit-flipping attack that works like this:
Let’s say this time Alice is not talking to Bob, but talking to her online bank. And she wants to send 100 dollars to someone. The message is encrypted with a secret key and sent to the bank via the internet.
Now Harry catches the encrypted message. Although he can’t decrypt it, he can flip some of its bits from 1 to 0 and from 0 to 1, then forward that modified message to the bank.
Now when the bank decrypts it, they will get a different plaintext content. In this case, it has become 900 dollars instead of 100.
So it’s very dangerous. That’s why we need to make sure that the encrypted message hasn’t been altered during transmission.
One way to do that is to use Authenticated Encryption. The idea is to not just encrypt, but also authenticate the encrypted message.
The first step is to encrypt.
Alice’s plaintext message goes through a symmetric encryption algorithm, such as AES-256-GCM or CHACHA20.
This encryption algorithm also takes a shared secret key and a random nonce, or an initialization vector (IV) as input. And it will return the encrypted message.
The second step is to authenticate.
The encrypted message, the secret key, and the nonce become inputs of a MAC algorithm, such as GMAC if you use AES-256-GCM, or POLY1305 if you use CHACHA20 encryption algorithm.
This MAC algorithm acts like a cryptographic hash function, and its output is a MAC, or message authentication code.
Now this MAC will be tagged along with the encrypted message, and the final result will be sent to Bob. Because of this, we sometimes call this MAC an authentication tag.
Add some Associated Data (AD)
In TLS 1.3, besides the encrypted message, we also want to authenticate some associated data, such as: the addresses, the ports, the protocol version, or the sequence number. This information is unencrypted and known by both communicating parties.
So the associated data is also an input of the MAC algorithm. And because of this, the whole process is called Authenticated Encryption with Associated Data, or in short, AEAD.
Decryption and MAC verification
Now let's see how Bob can check that the encrypted message hasn’t been changed during transmission.
It’s simply a reverse process. Starting with the encrypted message with MAC, we untag the MAC from the encrypted message.
Then the encrypted message will go to the MAC algorithm together with the shared secret key and the nonce. Note that this is the same nonce that is used in the encryption process. Usually the nonce is padded to the encrypted message before sending to the receiver.
The associated data will also go into the MAC algorithm. And the output of it will be another MAC.
Now Bob can simply compare the 2 MAC values. If they’re different then he knows that the encrypted message has been changed. Else, he can safely decrypt the message and use it with the confident that it’s the same plaintext message that Alice sent.
However, there’s 1 question: How Bob and Alice share the secret key with each other without leaking it to the public?
Well, the answer is: they need to use asymmetric or public-key cryptography for that purpose. Specifically, they can use either Diffie-Hellman Ephemeral, or Elliptic-Curve Diffie-Hellman Ephemeral.
Let’s see how Diffie Hellman key-exchange works!
First, Alice and Bobs both agree on 2 numbers: the base g, and the modulus p. These numbers are known publicly by everyone.
Then each of them secretly choose a private number. Alice’s private key is number
a, and Bob’s private key is number
Then Alice computes her public key and sends it to Bob:
A = (g^a) mod p
Similarly, Bob computes his public key and sends it to Alice:
B = (g^b) mod p
Then Alice will receive Bob’s public key
B, and Bob will receive Alice’s public key
Now the magic happens!
S = (B^a) mod p
S = (A^b) mod p
And these 2 values magically equal to the same number S.
Why? Let's do the math:
(B^a) mod p = (g^b)^a mod p = ( g^(b*a) ) mod p (A^b) mod p = (g^a)^b mod p = ( g^(a*b) ) mod p
So Alice and Bob come up with the same secret number S without leaking it to the public.
Each encryption algorithm may require a secret key of different length. So to make the secret key, Alice and Bob must put S to the same key derivation function (KDF), and the output will be a shared secret key of required length.
In TLS 1.3, we use a HMAC-based key derivation function, so that’s why the name
Generally, the KDF takes following inputs:
- An input key material (or IKM). In our case, the IKM is the number
- How long we want the output key to be, such as
- A cryptographic hash function, such as
- Optionally some context or application-specific information
- An optional salt.
With all of these inputs, KDF will produce a secret key of required length.
Now let's get back to the Diffie-Hellman key exchange.
We know that
p, g, A, B are known to the public, which means the hacker, Harry, also has access to those numbers.
We may wonder: Is this key exchange mechanism secure? Or given
p, g, A, B, can Harry figure out the secret numbers:
a, b, S?
Fortunately, these functions will be come trapdoors if we choose good values for
p, g, a, b.
gas a primitive root modulo
- And choose
a, bto be
A trapdoor function basically means it’s easy to compute in one way but hard in the other. In this case:
p, g, a, its’s easy to compute
- But given
p, g, A, it’s very hard to compute
It’s easy to see that
A can be computed pretty fast with
O(log(a)) time complexity. It’s a well-known Modular exponentiation problem.
a, on the other hand, is much harder. It’s a Discrete logarithm problem, which takes our current-generation of computers a very long time to solve.
So we’re at least safe for now, or until the next generation of strong quantum-computers comes into play.
However, for now, “a long time to solve” doesn’t mean unsolvable, right?
If Alice and Bob use the same private keys
b for every sessions that they communicate, then what happens is, Harry can record all of those sessions, and start solving for
a from the session 1.
Although it will take him a long time to solve it, let’s say after session
N, he gets the right
a. Now he can use it to compute the secret number
S, and thus, he would be able to decrypt all of the recorded conversations.
Does it sound scary? How can we prevent it?
The answer is ephemeral key. As the name may suggest, we use different private key or each session. So even if Harry can solve the secret key for 1 session, he could not use it for other ones.
This is called perfect forward secrecy in TLS.
So now you understand what Diffie-Hellman Ephemeral means. It’s just Diffie-Hellman with ephemeral or short-lived keys.
How about Elliptic-Curve Diffie-Hellman Ephemeral?
Elliptic-curve cryptography (or ECC) is an approach to asymmetric cryptography, where the algorithm is similar, but a different trapdoor function is used.
That trapdoor function is based on the algebraic structure of elliptic curves. And that’s why the name.
One amazing value of elliptic curve cryptography is: it requires smaller keys to provide the equivalent security level. You can see it in this comparison with RSA.
The U.S. National Security Agency (NSA) used to protect their top secret with ECC 384-bits key, which provides the same security level with a RSA-7680 bit key.
Sounds amazing, right?
However, Elliptic curve cryptography is an easier target for quantum-computing attack. Shor’s algorithm can break ECC on a hypothetical quantum computer with less amount of quantum resources than to break RSA.
There might be decades before that strong quantum computer actually be built and used. But have we prepared anything for that yet? Is there any quantum-resistant algorithm?
Yes, there is Supersingular Isogeny Diffie-Hellman key exchange algorithm, which is also based on the Elliptic Curve Cryptography.
But that’s another story though.
Now let’s get back to asymmetric cryptography! It’s an awesome technology that has a wide range of applications.
We’ve already explored 1 of its application, which is for symmetric secret key exchange, with Diffie-Hellman Ephemeral and Elliptic-Curve Diffie-Hellman Ephemeral.
In fact, RSA algorithm was also used for key exchange in the past, but it has been removed in TLS 1.3 due to various attacks and no forward-secrecy capability.
Asymmetric cryptography is also used in encryption system. Here are asymmetric encryption algorithms:
- RSA with optimal asymmetric encryption padding (RSA-OAEP).
- RSA with public key cryptography standard 1 (RSA-PKCS1) with the latest version 2.2
- Elgamal Encryption algorithm.
And finally, another important feature of asymmetric cryptography is for digital signature, which TLS uses extensively for authentication.
Some popular digital signature algorithms used in TLS are:
- RSA with Probabilitic Signature Scheme.
- Elliptic-Curve Digital Signature Algorithm.
- Edwards-Curve Digital Signature Algorithm.
We will learn about digital signature shortly. But before that, let’s learn how asymmetric encryption system works.
Similar as in symmetric encryption, Alice has a plaintext message that she wants to send to Bob.
But this time, there’s no shared secret key. Instead, Alice encrypt the message with Bob’s public key, and send the encrypted message to Bob.
When Bob receives the message, he uses his private key to decrypt it.
Although the public key and private key are different, they are still connected by some trapdoor function, just like what we’ve seen in the Diffie-Hellman algorithm.
The idea is: keys come in pair, and only the private key of the same pair can decrypt the message encrypted with its public key.
Because of this, even when Harry the hacker has access to both Alice’s encrypted message and Bob’s public key, he cannot use that public key to decrypt the message.
The public key sharing is very simple. Bob just send the key to Alice directly over the public internet without the fear that the key can be used to decrypt any messages.
The key is public, so anyone can use it to encrypt messages that only Bob can read, even if they have never talked to each other before. It’s really mind-blowing, isn’t it?
However, life’s not that so easy!
Although we know that Harry cannot decrypt the message with Bob’s public key, he can still interfere with the public key sharing, and replace Bob’s public key with his own public key.
Now when Alice receive the key, she still thinks it’s Bob’s public key, but it’s in fact Harry’s. So if Alice encrypts her message with this key, Harry would be able to decrypt it with his private key.
The reason this can happen is because a key is simply just a number, and there’s no identity information to tell us who its owner is.
So what can we do? Obviously, we should put the key together with some identity information. And that’s nothing else but a digital certificate.
So Bob puts his key inside his certificate, which has his name and other identity information on it. The certificate acts like a passport in the real world.
But how do we know it’s really Bob who owns that certificate? What stops Harry from making a fake certificate under Bob’s name but with Harry’s public key?
Well, just like in the real world, the passport must be issued by a passport authority after a process of identity verification. In digital world, the certificate must be verified and signed by a certificate authority.
This certificate authority and passport authority are trusted third party, who helps us prevent creation of fake passport and digital certificates.
The certificate signing process happens like this:
- Bob has a pair of public and private key.
- In the first step, he creates a certificate signing request, or CSR. This CSR contains his public key and some identity information, such as his name, organization, and email.
- Then the second step, he signs the CSR with his private key, and sends it to the certificate authority.
- The certificate authority will verify Bob’s identity in the certificate. They can contact him to ask for more proof if necessary.
- Then they use Bob’s public key in the certificate to verify his signature. This is to make sure that Bob really owns the private key that paired with the public key in the certificate.
- If everything is valid, the CA will sign the certificate with their own private key, and send it back to Bob.
Now Bob will share with Alice this certificate, which contains his public key, instead of sending just the public key as before.
Upon receiving the certificate, Alice can easily verify its authenticity with the public key of the Certificate authority.
Because of this, Harry cannot replace Bob’s public key with his key anymore, since he doesn’t have the CA’s private key to sign the fake certificate.
Note that this only works because we all trust the Certificate Authority. If somehow the CA is not trustworthy, for example, if they give Harry their private key, then we’re in a serious trouble!
In reality, there’s a chain of certificate authorities.
At the top level is a root certificate authority, who signs their own certificate, and also signs the certificate of their subordinate, which is an intermediate certificate authority.
This authority can sign the certificate of other intermediate authorities, or they can sign the end-entity certificate (or leaf certificate).
Each certificate will reference back to the certificate of their higher level authority, up to the root.
Your operating systems and browsers store a list of certificates of trusted root certificate authorities. That way they can easily verify the authenticity of all certificates.
We’ve talked a lot about signing a digital signature, so let’s see how it really works!
To sign a document:
- The signer first need to hash it.
- Then the hash value is encrypted using the signer’s private key.
- The result will be the digital signature.
- Then this signature will be attached to the original document.
And that’s it for the signing process. Now how can we verify that the signature is valid?
Well, we just do a reversed process:
- First we detach the signature from the document
- Decrypt it with the signer’s public key to get a hash value.
- Then we hash the document with the same hash algorithm used in the signing process.
- The result is another hash value.
- Then we just compare the 2 hash values.
- If they’re the same then the signature is valid.
OK, so now with all the knowledge we’ve gained so far, let’s take a closer look at how they’re used in the TLS handshake protocol.
The TLS 1.3 full handshake starts with a hello message that the client sends to the server. Actually this message contains a lot of things, but here I just list some important information:
- First, a list of protocol version that client supports.
- Then a list of supported AEAD symmetric cipher suites. In this case, there are 2 options: AES-256-GCM or CHACHA20-POLY1305
- After that, there’s a list of supported key exchange groups. For example, this client supports both Finite field Diffie-Hellman Ephemeral and Elliptic-Curve Diffie-Hellman Ephemeral.
- That’s why client also shares its 2 public keys, 1 for Diffie-Hellman, and the other for Elliptic-Curve Diffie-Hellman. This way, the server will be able to compute the shared secret key no mater what algorithm it chooses.
- The last field client sends in this message is a list of signature algorithms it supports. This is for server to choose which algorithm it should use to sign the whole handshake. We will see how it works in a bit.
After receiving the client hello message, the server also sends back its hello message,which contains:
- The selected protocol version TLS 1.3
- The selected cipher suites: AES-256-GCM
- The selected key exchange method: Diffie-Hellman Ephemeral
- And the server’s public key for that chosen method.
- The next field is a request for the client’s certificate, which is optional and will only be sent if the server wants to authenticate the client by its certificate.
- Normally on a HTTPS website, only the server side needs to send its certificate to the client. And that is sent in the next field of this message.
- The next field is certificate verify, which is, in fact, the signature of the entire handshake up to this point. Here’s how it is generated: The whole data from the beginning of the handshake up to the certificate request is called a handshake context. We concatenate this context with the server’s certificate, hash it, and sign the hash value with the server’s private key using 1 of the signature algorithms that the client supports.
- In a similar fashion, the server finish is generated by concatenating the handshake context, the certificate, and the certificate verify, hash it, and put the hash value through the MAC algorithm of the chosen cipher suite. The result is the MAC of the entire handshake.
Here the server certificate, certificate verify, and server finish are called authentication messages, because they are used to authenticate the server. With the signature and MAC of the entire handshake, TLS 1.3 is safe against several types of man-in-the-middle Downgrade attacks.
Now after the client receives the hello message from server, it will validate the server’s certificate with the root authority, and check the signature and MAC of the entire handshake to make sure it’s not been tampered with.
If everything is good then the client sends its finish message with the MAC of the entire handshake up to this point, and optionally the client’s certificate and certificate verify in case the server has requested.
And that’s the whole flow of the full TLS handshake.
To improve the performance, the client and server don’t always go through this full handshake. Sometimes, they perform abbreviated handshake by using preshared key resumption.
The idea is: after the previous handshake, the client and server already know each other, so they don’t need to authenticate again.
So the server may send one or multiple session tickets to the client, which can be used as the pre-shared key (PSK) identity in the next handshake. It goes with a ticket lifetime as well as some other information.
Now in the next handshake, the client will send a simple hello message, which contains:
- A list of PSK identities (or tickets) obtained from the previous handshake
- A PSK key exchange mode, which can be either PSK only, or PSK with Diffie-Hellman.
- If the PSK with Diffie-Hellman mode is used, then the client also needs to share its Diffie-Hellman public key. This will provide perfect forward secrecy, as well as allow the server to fallback to full handshake if needed.
When the server receives this client hello message, it sends back its hello with:
- The selected pre-shared key identity
- The optional Diffie-Hellman public key of the server
- And the server Finish just like in the full handshake.
Finally the client sends back its Finish, and that’s the end of the PSK resumption.
As you can see, there’s no certificate authentication between client and server in this abbreviated handshake.
This also opens up an opportunity for zero round-trip time (0-RTT) data, which means, the client doesn’t need to wait for the handshake to complete to send its first application data to the server.
In 0-RTT, client sends the application data together with the client hello message. This data is encrypted using the key derived from the first PSK in the ticket list.
And it also adds 1 more field: early data indication to tell the server that there’s early application data being sent along.
If the server accepts this 0-RTT request, it will sends back the server hello just like in the normal PSK resumption, and optionally some application data as well.
The client will finish with a message containing the MAC, and an end-of-early-data indicator. That’s how 0 round-trip time works in TLS 1.3.
Its pros is reduce the latency by 1 round trip time. But the cons is openning up a potential threat of replay attack. Which means, the hacker can just copy and send the same encrypted 0-RTT request to the server multiple times. To avoid this, the server application must be implemented in a way that’s resilient to duplicate requests.
Now before we finish, let’s do a quick comparison of TLS 1.3 and TLS 1.2 to see what’s new!
TLS 1.3 has safer key exchange mechanisms, where the vulnerable RSA and other static key exchange methods are removed, leaving only ephemeral Diffie-Hellman or Elliptic-Curve Diffie-Hellman remain, therefore achieved perfect forward secrecy.
TLS 1.3 handshake is at least 1 round-trip faster than TLS 1.2.
Symmetric encryption in TLS 1.3 is more secure because AEAD cipher suite is mandatory, and it also removes some weak algorithms from the list such as Block Cipher Mode (CBC), RC4, or Triple DES.
The cipher suite in TLS 1.3 is also simpler, since it only contains the AEAD algorithm and a hash algorithm. The key exchange and signature algorithms are moved to separate fields. While in TLS 1.2, they’re merged into the cipher suite. This makes the number of recommended cipher suites become too big, 37 options in TLS 1.2 if i remember correctly. While in TLS 1.3, there are only 5.
Next, TLS 1.3 also give us stronger signature, since it signs the entire handshake, not just cover some part of it as in TLS 1.2.
Last but not least, Elliptic-curve cryptography gets a significant attention in TLS 1.3, with some better curves algorithm added, such as Edward-curve digital signature algorithm, which is faster without sacrificing security.
And that’s everything I want to share with you in this article. Thanks for reading, and I’ll catch you guys in the next one!
Claim your page on DEV before someone else does
Level up every day