Decrypting HTTPS traffic with Wireshark

Using TLS to secure websites is slowly becoming universal. Projects like Let's Encrypt are making it easier to setup HTTPS, and adoption is increasing. One of the few downsides to HTTPS is debugging traffic with tools like Wireshark can be harder. It is however possible to decrypt HTTPS traffic with Wireshark.

Example setup

The example in this post is going to go over capturing and decrypting an HTTP request made with curl:

HTTPS diagram

To decrypt the request, the following info will be required:

  • The private key from the web server.
  • A complete packet capture of the request, taken on either the server or on the client.

Note: if a key exchange method with perfect forward secrecy such as ephemeral Diffie-Hellman is used; it won't be possible to decrypt the message without additional information.

Client and server software

Under CentOS curl, wireshark and tcpdump can be installed from the CentOS repos:

yum install -y wireshark tcpdump curl

Apache can be installed and set up on the server with the following commands:

yum install -y mod_ssl httpd
systemctl enable httpd
systemctl start httpd
echo 'Hello world' > /var/www/html/message.txt

Capturing traffic

A tcpdump command similar to the following can be run on the client to capture packets sent to/from the web server (10.0.2.10):

tcpdump -w /tmp/https.pcap -B 40960 host 10.0.2.10

Once tcpdump is listening, the following curl command can be run to make the HTTP request:

curl --insecure --ciphers rsa_aes_256_cbc_sha_256 https://10.0.2.10/message.txt

Once curl has finished, press ctrl + c to kill tcpdump.

Note: the --ciphers option is used to force curl to use RSA for the key exchange. This makes it possible to decrypted traffic in the packet capture with the server's private key.

Decrypting traffic

Initially opening up the packet capture in Wireshark will look something like this:

HTTPS packet capture opened in Wireshark with the data encrypted.

To decrypt the traffic go to Edit -> Preferences, find SSL under Protocols and add a new RSA key. The key should be the private key from the web server, the protocol should be http, the port should be 443 and the IP address should match the IP address of the web server in the packet capture:

Settings to decrypt HTTPS traffic in Wireshark.

If everything works as expected, after clicking Apply the HTTP requests should now be decrypted and visible in Wireshark:

HTTPS packet capture opened in Wireshark with the data decrypted.

Note: if the steps above don't work double check the client key exchange protocol being used is RSA or try setting SSL debug file to collect debug information from Wireshark.