Overview and Dissection of TLS 1.3 Handshake using Wireshark











Objectives


By the end of this guide, you will
  • have a basic understanding of how TLS 1.3 handshake works
  • be able to use curl to make request and get additional information such as the IP address of web server, TCP port, etc
  • be able to capture and filter packets using wireshark
  • be able to log pre-master secrets and use them to decrypt TLS traffic

Overview


TLS 1.3 is a major overhaul of the TLS protocol with enhanced speed, improved efficiency and better security. Ciphers and algorithms which are considered weak and insecure have been removed in the latest TLS version. These include RSA key exchange, 3-DES, DES and RC4 stream cipher among many more. As a result, the number of cipher suites dropped from 37 to 5. RSA key exchange was removed since it does not provide forward secrecy. This means that if the private key of the server is leaked in the future, the ciphertexts can be decrypted. Moreover RSA for key exchange is vulnerable to Bleichenbacher attacks.  In TLS 1.3 all key exchange algorithms were removed except for Diffie-Hellman (DH).

Additionally TLS 1.3 requires servers to sign the entire handshake including the cipher negotiation unlike TLS 1.2. Furthermore, TLS 1.3 takes only one round trip to complete a handshake whereas TLS 1.2 takes two round trips. This is possible because the client guesses the parameters the server will use and can therefore send the DH key share in the first handshake message itself (Client Hello). 


Prerequisites

  • Wireshark
Run sudo apt install wireshark

  • Curl
Run sudo apt install curl


Capturing the packets and SSL key log

 
  • Open terminal and set the SSLKEYLOGFILE environment variable to the full path of the file to which you want to save key log. Ensure you have write permission to the location you specify. Run: 
export SSLKEYLOGFILE=$HOME/Desktop/keylog

Note: A key log is a log/record of values which are used to generate TLS session keys. 

  • Open wireshark in another tab in terminal and start capture
 To open wireshark, run sudo wireshark 
 Double click on the appropriate network interface to start capture. Alternatively, you can right click and choose "start capture".

  • Use curl to make request to a server which supports TLS 1.3
Ensure that you are in the same terminal in which you set the SSLKEYLOGFILE environment variable. You can run echo $SSLKEYLOGFILE  to ensure that it is set.

Note: If you want to access the website through chrome (google-chrome https://google.com) or firefox (firefox https://google.com), make sure you open the web browser from that terminal.

Close all browsers and run curl https://google.com -v

 


 The output should look similar to the screenshot above. The IP address of the web server is found to be 172.217.170.174

At this point, the key log file you specified in the first step should have been automatically created and written to. 

 

  • Stop capture and filter the packets
Use the following filter to display only packets involving the web server of that website and which uses TLS protocol:

tls && ip==172.217.170.174



Analyzing the packets



At first glance, it can be seen that:
  1. The client first sends Client Hello to the server
  2. The server responds with Server Hello followed by Change Cipher Spec unlike TLS 1.2.
  3. The server also sends some encrypted application data along.
  4. The client sends a Change Cipher Spec to the server together with some encrypted data. The rest of the conversation is encrypted as well.

Now we will use the client key log file to decrypt the TLS traffic.

On Wireshark, go to Edit ->Preferences->Protocols->TCP. Then change the (Pre)-Master-Secret log filename to the location of the key log file and click OK.



Wireshark will convert the pre-master to the master key and decrypt all the encrypted application data of the conversation.


Making sense of the TLS 1.3 handshake



1.  Client sends Client Hello


It's odd to see the client request a TLS 1.2 handshake. This happens because TLS 1.3 is a victim of protocol ossification. A large number of servers implemented TLS version negotiation wrongly. When presented by the client with a version of TLS higher than what they support, those servers disconnect instead of replying with the newest TLS version which both of them support. 

In order to be compatible with previous versions, TLS 1.3 disguises itself as a TLS 1.2 handshake and introduces extensions to add functionality to it. 

The latest TLS version which the client supports is actually found in the supported_versions extension.

 

The Client Hello includes the latest version the TLS version, a list of Cipher Suites the client supports, the client random and the key_share extension.

The key_share contains the client parameter for key exchange.

 

  

The client guesses which key exchange method the server is likely to choose and its key share for that particular method is sent. If ever the guess is wrong, the server sends a Retry Hello Request Message.


2.  Server sends Server Hello and Change Cipher Spec

 


  

In the supported_versions extension, the server confirms the TLS version.

 


The key_share extension has the selected curve name and server key exchange parameter. 

The Server Hello also contains the server random.

At this point, the server has the client random, the server random and both the key shares of the client and the server. Therefore the server can generate the master secret from which the session key is calculated and can start encrypting messages. So it sends Change Cipher Spec to let the client knows that it has generated the session key and is switching to an encrypted environment.


 

3.  Server sends Encrypted Extensions, Certificate, Certificate Verify and Finished

All those messages are encrypted using the session key and sent to the client. 

The Encrypted Extensions message contains additional extensions which can be protected but which are not needed to establish the encrypted connection. If there is no such extension, the message is empty.



 


 

 



Certificate contains the server's digital certificate and any per-certificate extensions. 

Certificate verify : the entire handshake is signed using the private key of the server corresponding to the public key in the certificate message. 

Finished contains a MAC to ensure integrity of handshake. It is sent to indicate that handshake is done on the server side.

 

4.  Client sends Change Cipher Spec and Finished.

Change Cipher Spec is sent to let the server know that the client has generated the session key and is switching to an encrypted environment. 

Finished contains a MAC to ensure integrity of handshake. It is sent to indicate that handshake is done on the client side.

 

Comments