You made it to part 4! Here’s a quick overview of what we have broken down so far. We started with some basic vocabulary for cryptographic building blocks and talked about hash functions in Part 1, were introduced to symmetric ciphers, keys, and leakage in Part 2, and dove into asymmetric ciphers in Part 3. We’ve covered a lot, and we aren’t quite done! In this section we are going to take the foundations we have learned and apply them in a TLS deep dive.
As with each of the chunks of this series, we are going to break things down one step at a time, just like the subreddit “Explain Like I’m Five” does! Let’s start with some key terms:
- TLS stands for Transport Layer Security. This is a protocol used for secure communication on the Internet.
- The TLS Handshake is the series of steps that occur at the beginning of a TLS session to negotiate a shared key.
- A digital certificate (or just certificate) is a document used to prove the identity of parties on the Internet.
- A cipher suite is a combination of algorithms to be used in concert while utilizing the TLS protocol. It defines the algorithms to be used in different steps of the protocol.
We will use these terms in context, so as usual don’t worry about memorizing! They will become familiar as we continue to revisit them. So first…
What is TLS?
TLS stands for Transport Layer Security, and it is a protocol that allows two parties to communicate over a network in a secure fashion. It will be a great reinforcement of the foundations introduced up to this point, because it employs a few different cryptographic techniques. We are going to talk specifically about how TLS leverages the cryptographic foundations covered in this series not about every detail and nuance in TLS.
Note: You may see TLS and SSL used interchangeably or referred to together. SSL stands for Secure Sockets Layer, and this was the now deprecated predecessor to TLS.
The goal of TLS is for two parties to be able to communicate securely. What pieces do we need in order to achieve this? Let’s say we are Alice, and we are trying to communicate with our friend Bob who lives very far away. We want to send Bob some information that no one else can read. This means we will need to pick a cipher to encrypt our data, and, since Bob lives far away, we want to consider how we will share the key for the cipher we choose. Should we pick a symmetric cipher or an asymmetric cipher to encrypt our messages?
This is a little bit of a trick question. As we learned in the last couple of parts in this series, ciphers require a key, but securely sharing this key between two parties can be challenging. Asymmetric cryptography leverages some interesting math and solves this for us! However, thinking back to Part 3, we also know that asymmetric cryptography is significantly slower to run than symmetric cryptography is. If we chose asymmetric cryptography to benefit from key sharing from a distance, we would sacrifice on performance. But if we chose symmetric cryptography for better performance, we would sacrifice on ease of key sharing. What do we do?
TLS actually uses a combination of asymmetric and symmetric cryptography to allow Alice and Bob to share a key securely at a distance but also to communicate efficiently. How does it do this? Well, TLS begins with a handshake, which is what we call the negotiation between the two parties, a client Alice and a server Bob. A negotiation is necessary, because it allows Alice and Bob to use asymmetric cryptography to decide on a secret key for their symmetric encryption and decryption. Once the handshake is complete, they can switch over to using symmetric cryptography for its speed, encrypting and decrypting with the key they negotiated.
Let’s take a look at the steps of a TLS handshake. There are lots of great diagrams online that outline the handshake. I like this one by ssl.com for an introduction to TLS, because it describes the handshake messages in an approachable way. Look through the steps, remembering that the diagram indicates the client with blue and the server with green. See if you can identify where the asymmetric encryption and decryption is happening!
Okay, so what is going on here? Starting at the top, the client sends an initial message to the server telling it what cipher suites it supports. A cipher suite is a combination of algorithms that should be used in different steps of the TLS protocol, including the signature algorithm, the symmetric ‘bulk’ encryption algorithm, and even key exchange algorithm. They typically look something like this, ECDHE-RSA-CHACHA20-POLY1305, with the different algorithm names capitalized and concatenated. The client provides this information to kick off the TLS session and get ready to establish a secure communication channel.
Next, the server responds by telling the client which of the supported cipher suites they will use moving forward and gives the client its certificate to 1) verify identity, and 2) encrypt a secret key for use later on.
Let’s take a quick moment to talk about what a certificate is and how it can be used to take care of the two items above. If you are familiar with certificates, feel free to skip this paragraph. A certificate contains its owner’s public key along with some important information about the identity of the owner. A Certificate Authority (CA) has to approve certificate requests by validating the information submitted and signing off that the public key belongs to that verified owner. Then, anyone who wishes to verify someone’s certificate can check that the certificate was signed by a trusted CA.
As the diagram describes, once the client receives the Server Hello, it verifies that the certificate was issued by someone it trusts then extracts the trusted public key. Next, the client uses the server’s public key to encrypt secret data, called the pre-master secret or master key, and shares it with the server. Each party then uses the pre-master secret to compute a shared secret key for symmetric encryption. So, when we arrive at the bottom blue and green box in the diagram, the two parties are able to switch to using faster symmetric encryption with the shared key that they negotiated using asymmetric encryption. Phew!
TLS in Brief
Remember, this series of messages required to set up an encrypted TLS session is typically referred to as a TLS handshake. In short, the handshake has the following steps with named messages:
- Client Hello
- Server Hello, Server Certificate and Key Exchange, Server Hello Done
- Client Key Exchange, Change Cipher Spec, Client Hello Done
- (from server) Change Cipher Spec, Finished
Take a minute to see if you can match the four steps above with the diagram we went over earlier. Keep in mind that one step can map to multiple boxes/arrows in the diagram!
How’d it go? The first blue arrow represents the Client Hello, the first green arrow represents the Server Hello, Server Certificate and Key Exchange, and Server Hello Done. The next two blue arrows represent the interaction for Client Key Exchange, Change Cipher Spec, and Client Hello Done. The final green arrow represents the server’s Change Cipher Spec and Finished messages, then we arrive at the blue-green arrow where we now have an encrypted channel!
Create our own TLS Session!
We can set up our own TLS connection using OpenSSL in a terminal. Let’s go to our terminal and first generate a key pair and certificate for our local server to use. Since we are just doing this as a contextual example, we aren’t going to get this signed by an actual CA. We are just going to create a self-signed certificate instead. In Part 3 we generated a key using OpenSSL. This is going to look similar, but we are going to generate both a key and a certificate in one step:
$ openssl req -x509 -newkey rsa:2048 -keyout -server_key.pem -out server.crt -days 365
This will generate a new RSA key pair and a certificate that is valid for 365 days. It will prompt you for a passphrase for the private key. Enter whatever you choose, just don’t forget! Next, it will prompt you for some information that goes into the certificate such as Country Name, Organization Name, etc. You can skip some of these steps by leaving them blank but enter ‘localhost’ for the Common Name, since we will be running our server locally.
You can see what each of these files contains using ‘cat’:
$ cat server_key.pem
$ cat server.crt
Now, let’s use these files to run a server and connect with TLS. OpenSSL has lots of helpful utilities, including two called s_server and s_client. These allow us to run a server and a client with minimal code writing! In order to start our server, we just need to supply s_server with our key and certificate files:
$ openssl s_server -cert server.crt -key server_key.pem
This command will prompt you for your key passphrase, then it will tell you what defaults are set up followed by ‘ACCEPT’, which means the server is running and ready for connections! s_server serves on port 4433 by default. You can see other options and defaults by using:
$ openssl s_server -help
Let’s open one more terminal window without closing our server’s window. In this second window, we are going to connect to our server using s_client. We just have to supply it with a hostname and a port number:
$ openssl s_client -connect localhost:4433
When you hit enter, the client initiates a TLS Handshake with the server you set up in your other window. Look through the output to see what looks familiar. You may see an error at the top about the certificate being self-signed. This is okay, since we are just testing for ourselves. Don’t get in the habit of disregarding this warning message. We don’t want to see this error in other circumstances! It means a trusted Certificate Authority didn’t verify the server identity, and a bad player could be attempting to fool you.
As you look through the output, you should see the server certificate printed out along with the server’s common name, then you’ll see a line similar to:
‘New, TLSv1/SSLv3, Cipher is ECDHE-RSA-CHACHA20-POLY1305’
This tells us that we have established a new TLS session, and the agreed upon cipher suite is ECDHE-RSA-CHACHA20-POLY1305. Toward the bottom of the output, you’ll see more details about our TLS session. Do you see anything familiar?
The cipher suite is shown there again, and you should also see the master key. Remember this is the data that the server and client will each use to calculate a shared secret key for use in symmetric encryption/decryption.
You’ve got a secure communication channel between two ports on your local machine! A similar process happens when you are connecting to a website via a browser, only we expect a verifiable certificate and begin to exchange more website data after the connection is opened. If a secure channel is successfully opened from a browser, this is when you will see the lock icon near the address bar.
For now, you can Ctrl+C to stop the server and client from running. If you enjoyed this, you might also want to follow this same process but watch the connection get established using Wireshark! You’ll need to capture traffic on the loopback interface, then run your server and client again. There, you can see the different steps in the TLS Handshake and dig a little deeper into what information is included within each step.
Thanks for sticking with me! We have covered a lot of foundational cryptography concepts throughout the course of this series, and in this article you successfully applied these foundations!
Ellie Daw is passionate about diversity in tech and giving back, innovation and experimentation, and bringing security and good user experience together. She loves cryptography, hence her handle @cryptoreo, and has been heavily involved in teaching cryptography to professionals as well as developing cryptography workshops for youth cybersecurity education initiatives. On the technical side, Ellie has spent the last couple of years working as a software engineer on crypto and network protocol libraries. She believes there is always more for her to learn, but understands the importance of letting loose, too! In her free time you can find her exploring new places and trying new foods, or dabTags: crypto daw highlight openssl tls tutorial