Using tshark to Decrypt SSL/TLS Packets

I’m going to walk you through the process of decoding SSL/TLS traffic from a pcap file with the server’s private key using tshark (command-line version of Wireshark). You can, of course, always use ssldump for the same purpose.

I assume you know how SSL/TLS works, and basic understanding of how Wireshark works, and why we use it.

I will start with getting a sample encrypted traffic that includes the handshake part (important for decryption later). For that purpose, we are going to use openssl command to generate a pair of server certificate and key. And then run the HTTPS server with openssl’s s_server command on port 4443 (or any other port you may like) using the generated certificate and key. Then we will issue a GET request to HTTPS server via curl. In the mean time, we will collect the traffic with tshark and will save the data into ssltest.pcap file.

# [1] create RSA cert and key pair
openssl req -new -x509 -out server.crt -nodes -keyout server.pem -subj /CN=localhost

# [2] run the server using the above
openssl s_server -www -cipher AES256-SHA -key server.pem -cert server.crt -accept 4443

# [3] from another console session, start capturing the traffic, on loopback interface
# (you will need to change lo0 to the relevant interface on your system.
tshark -s0 -w ssltest.pcap -i lo0

# [4] generate traffic from another console
curl -vk https://localhost:4443

# [5] Ctrl+C on the tshark command at [3], and stop the openssl server at [2]

At this point, we should have the file called ssltest.pcap from tshark, and server.crt/server.pem from openssl commands.

Next, we are going to read the pcap file and decode the traffic.

# [1] it shows the encrypted traffic
tshark -r ssltest.pcap

# [2] for details of the packets
tshark -r ssltest.pcap -V

# [3] for decrypted data; ssl.keys_list points to the RSA key
# added -x for hex dump
# At the output you should see the message in packet detail:
#  >>> Decrypted SSL record (16 bytes):
# And the decrypted data:
# >>> Hypertext Transfer Protocol
# >>>    GET / HTTP/1.1\r\n
tshark -r ssltest.pcap -V -x -o "ssl.debug_file:ssldebug.log" -o "ssl.desegment_ssl_records: TRUE" -o "ssl.desegment_ssl_application_data: TRUE" -o "ssl.keys_list:,4443,http,server.pem"

# [4] inspecting ssldebug.log output from [3]
# You should see the following messeage near the top of the file:
#   >>> ssl_init private key file server.pem successfully loaded.
cat ssldebug.log

In Wireshark GUI, we can follow “SSL stream” that will dump the ASCII output from the stream. How are we going to do it with tshark?

# We add -z to show the statistics with option 'follow,ssl,ascii,1'
# to follow ssl stream number 1
# -q to suppress packet dumps
tshark -r sslsample.pcap -q -o "ssl.keys_list:,4443,http,server.pem" -z "follow,ssl,ascii,1"

You will see the output similar to below:

Follow: ssl,ascii
Filter: eq 1
Node 0:
Node 1:
GET / HTTP/1.1
Host: localhost:4443
User-Agent: curl/7.43.0
Accept: */*

HTTP/1.0 200 ok
Content-type: text/html


s_server -www -cipher AES256-SHA -key server.pem -cert server.crt -accept 4443
Ciphers supported in s_server binary
Ciphers common between both SSL end points:
AES256-SHA                 AES128-SHA                 DES-CBC3-SHA
ECDH-RSA-RC4-SHA           RC4-SHA                    RC4-MD5
New, TLSv1/SSLv3, Cipher is AES256-SHA
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: B9AE3B24559606A2723F987F21E9C202EDB19366098286083F3BDCDABE45B300
    Session-ID-ctx: 01000000
    Master-Key: 98DC04D8CD7AE943A08BE013CD4C7D0608950BC201B953BC12755EC9B4804D453148173B00043EF6A01CAC43F7B0005C
    Key-Arg   : None
    Start Time: 1453795701
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
   2 items in the session cache
   0 client connects (SSL_connect())
   0 client renegotiates (SSL_connect())
   0 client connects that finished
   2 server accepts (SSL_accept())
   0 server renegotiates (SSL_accept())
   2 server accepts that finished
   0 session cache hits
   0 session cache misses
   0 session cache timeouts
   0 callback cache hits
   0 cache full overflows (128 allowed)
no client certificate available


3 responses for Using tshark to Decrypt SSL/TLS Packets

  1. Joe says:

    I am trying to accomplish what you have layed out so in detail but unfortunately my lack of unix and networking experience works against me. I am able to capture packets using tshark on an apache server that hosts a REST api. I first tried on a dev server where https was not enforced and was able to clearly read the packets. On the production server it is https and the packets are encrypted. Could you perhaps assist in which steps from above I will require to decrypt the packets.

  2. Pete says:

    tshark -r ssltest.pcap -V -x
    -o “ssl.debug_file:ssldebug.log”
    -o “ssl.desegment_ssl_records: TRUE”
    -o “ssl.desegment_ssl_application_data: TRUE”
    -o “ssl.keys_list:,4443,http,server.pem”

    The last line specifies the key to decrypt. The format is server,port,protocol,PrivateKey

  3. Jeff Nichols says:

    thank you very much for this information! there’s a lot going on and you make it seem relatively simple with a reproducible example to follow. now to move on to debugging the servers i’m having trouble with 🙂

    i think there is one typo in the “follow” command where the pcap filename you use is “sslsample.pcap” but it should be “ssltest.pcap”. i also wasn’t able to get the follow to work unless i used stream index 0. don’t know if this is a version change or something. i’m using tshark 1.10.14 and libpcap 1.5.3.

  4. Leave a Reply to Pete Cancel reply

    Your email address will not be published. Required fields are marked *