Decrypt TLS in Wireshark with the SSLKEYLOGFILE Method - 夜莺博客

Decrypt TLS in Wireshark with the SSLKEYLOGFILE Method

You have captured the packet stream, but everything worth reading is inside TLS — and because modern TLS uses ephemeral Diffie-Hellman, the server's private key will not help you. The key log file is the universal answer: browsers and command-line tools will write the per-session secrets to a file when told to, and Wireshark will use those secrets to decrypt the stream. It works with forward secrecy, which the RSA private key method does not. Here is the workflow, and the cases where it refuses to work.

Why the RSA Private Key Does Not Work Anymore

Capturing the server's private key only decrypts sessions that used RSA key exchange. With ECDHE or X25519 — which is essentially everything now — the session keys are derived from ephemeral values that never appear on the wire, so the private key is useless. The key log file sidesteps this entirely by recording the derived secrets at the endpoint.

Step by Step: Browser Capture

  1. Close the browser completely — check the task manager, a lingering process will not pick up the new environment variable.
  2. Set SSLKEYLOGFILE to an absolute path in a writable location.
  3. Start the browser from that environment.
  4. Confirm the file is created (it may be empty until the first TLS session).
  5. In Wireshark: Edit → Preferences → Protocols → TLS, set (Pre)-Master-Secret log filename to that path.
  6. Start the capture, then load a page over HTTPS.
  7. Filter with tls and (http or http2) — you should now see the decrypted request inside the TLS records.
# Linux
export SSLKEYLOGFILE=$HOME/Desktop/keylogfile.txt
firefox &

# macOS
export SSLKEYLOGFILE=$HOME/Desktop/keylogfile.txt
open -a firefox

# Windows - a .cmd wrapper avoids leaving the variable set system-wide
@echo off
set SSLKEYLOGFILE=%USERPROFILE%\Desktop\keylogfile.txt
start firefox

Do not set the variable globally on Windows. It makes every TLS session on the machine decryptable by anyone who can read that file — a real liability on a laptop that leaves the building.

Command-Line and Non-Browser Clients

SSLKEYLOGFILE=$PWD/secrets.txt curl -s https://example.com/ -o /dev/null
SSLKEYLOGFILE=$PWD/secrets.txt mitmproxy

OpenSSL 3.4 and later honour SSLKEYLOGFILE directly, which modernises this for any application built on it. Older OpenSSL builds need a GDB or LD_PRELOAD trick — and note that Python's default TLS stack historically required exactly that.

What the Key Log File Contains

CLIENT_RANDOM 3928c6de...f3cf4b25 fd87d5f05db3...e9c806868
SERVER_HANDSHAKE_TRAFFIC_SECRET 3928c6de... b8c81cee57...
CLIENT_HANDSHAKE_TRAFFIC_SECRET 3928c6de... 7aec5af056...
SERVER_TRAFFIC_SECRET_0 3928c6de... 7e40bb08f3...
CLIENT_TRAFFIC_SECRET_0 3928c6de... 7a31364a74...
EXPORTER_SECRET 3928c6de... bc8a82770f...

The long hex value repeated on every line is the client random, which is how Wireshark matches secrets to a session. Keep only the client-side lines and Wireshark decrypts only client-to-server data; keep only server-side lines and it decrypts only the other direction. If you see green HTTP inside the TLS record, decryption succeeded.

Embed Secrets in the Capture File

editcap --inject-secrets tls,keys.txt in.pcap out-dsb.pcapng

Since Wireshark 3.0 the key log can be embedded in a pcapng, so a colleague opening the file needs no preference changes. Remember to treat the resulting file as a credential: anyone with it can read the plaintext.

When It Does Not Work

  • TLS 1.3 with a session resumed or a non-exporting stack — some clients simply do not write the file. Safari and Edge rely on stacks that do not support this mechanism.
  • Custom TLS implementations — this is precisely why key-log decryption is useless against malware C2 traffic, which frequently ships its own TLS library.
  • Wrong path or permissions — if the process cannot write the file, it fails silently. Check tls.debug_logfile in Wireshark to see what secrets Wireshark actually loaded.
  • Capture started before the variable was set — sessions negotiated earlier are not in the log.

PSK-Encrypted Traffic

Some embedded devices use TLS with a pre-shared key. If you can obtain the PSK, enter it in hex in the Pre-Shared-Key preference and Wireshark decrypts every session using that key — past and future, since the key does not change.

Related Reading

Deeper dives on the same topics from our archive:

原文链接:https://wiki.wireshark.org/tls