53

How can I decrypt TLS messages when an ephemeral Diffie-Hellman ciphersuite is used? I am able to expose the premaster secret and master secret from the SSL Client. Using that, how to decrypt the messages in Wireshark?

mikeazo
  • 2,827
  • 12
  • 29
Kalai
  • 781
  • 2
  • 7
  • 5

2 Answers2

61

Some background: Wireshark supports decryption of SSL sessions when the master secret can be calculated (which can be derived from a pre-master secret). For cipher suites using the RSA key exchange, the private RSA key can be used to decrypt the encrypted pre-master secret.

For ephemeral Diffie-Hellman (DHE) cipher suites, the RSA private key is only used for signing the DH parameters (and not for encryption). These parameters are used in a DH key exchange, resulting in a shared secret (effectively the pre-master secret which is of course not visible on the wire).

Wireshark supports various methods to decrypt SSL:

  • By decrypting the pre-master secret using a private RSA key. Works for RSA key exchanges and subject to the above limitation.

  • Using a SSL keylog file which maps identifiers to master secrets. The available identifiers are:

    • The first 8 bytes (16 hex-encoded chars) of an encrypted pre-master secret (as transmitted over the wire in the ClientKeyExchange handshake message). (RSA XXX YYY, since Wireshark 1.6.0)
    • The 32 bytes (64 bytes hex-encoded chars) within the Random field of a Client Hello handshake message. (CLIENT_RANDOM XXX YYY, since Wireshark 1.8.0)
      • A variant that maps the Client Random to a pre-master secret (rather than master-secret) also exists. (PMS_CLIENT_RANDOM XXX ZZZ, since Wireshark 2.0)
      • Another variant exists to support TLS 1.3 and maps the Client Random to respective secrets. Instead of CLIENT_RANDOM, the key is one of CLIENT_EARLY_TRAFFIC_SECRET, CLIENT_HANDSHAKE_TRAFFIC_SECRET, SERVER_HANDSHAKE_TRAFFIC_SECRET, CLIENT_TRAFFIC_SECRET_0 or SERVER_TRAFFIC_SECRET_0. Since Wireshark 2.4.
    • The Session ID field of a Server Hello handshake message. (RSA Session-ID:XXX Master-Key:YYY, since Wireshark 1.6.0)
    • The Session Ticket in a Client Hello TLS extension or Session Ticket handshake message. (RSA Session-ID:XXX Master-Key:YYY, since Wireshark 1.11.3)

To generate such a SSL key log file for a session, set the SSLKEYLOGFILE environment variable to a file before starting the NSS application. Example shell commands for Linux:

export SSLKEYLOGFILE=$PWD/premaster.txt
firefox

On Windows you need to set a global environment variable, either via cmd (invoke setx SSLKEYlOGFILE "%HOMEPATH%\Desktop\premaster.txt" for example) or via the System configuration panel. After doing so, you can launch Firefox via the icon. Note: (Linux) users of Firefox with NSS 3.24+ are possibly unable to use this method because Firefox developers disabled this by default.

The SSL key log file can be configured for Wireshark at Edit -> Preferences, Protocols -> SSL, field (Pre)-Master-Secret log filename (or pass the -o ssl.keylog_file:path/to/keys.log to wireshark or tshark).

After doing this, you can decrypt SSL sessions for previous and live captures. Should you encounter a situation where you still cannot decrypt traffic, check:

  • whether the key log file path is correct (use absolute paths in case the program changes the working directory).
  • whether the key log file actually contains key material for your program.
  • whether Wireshark was compiled with GnuTLS (I have tested Wireshark 1.10.1 with GnuTLS 3.2.4 and libgcrypt 1.5.3)
  • whether other sessions can be decrypted. For instance, I tried https://lekensteyn.nl/ which works, but a site using a Camellia cipher suite failed.

If you still cannot decrypt all traffic, it is possible that Wireshark contains a bug (in my case it was missing support for Camellia). To start debugging, save your capture and start wireshark with SSL logging enabled:

wireshark -o ssl.debug_file:debug.txt savedcapture.pcapng

After the capture has been loaded, you can close the program again. (You do not actually need to save the capture, but it makes it easier to reproduce the issue and avoid further noise in the log dump.) You might see something similar to the line below:

ssl_generate_keyring_material not enough data to generate key (0x33 required 0x37 or 0x57)

These numbers are a combination of the constants defined in epan/dissectors/packet-ssl-utils.h:

215-#define SSL_CLIENT_RANDOM       (1<<0)
216-#define SSL_SERVER_RANDOM       (1<<1)
217:#define SSL_CIPHER              (1<<2)
218-#define SSL_HAVE_SESSION_KEY    (1<<3)
219-#define SSL_VERSION             (1<<4)
220-#define SSL_MASTER_SECRET       (1<<5)
221-#define SSL_PRE_MASTER_SECRET   (1<<6)

As you can see, I am missing the SSL_MASTER_SECRET (0x20) here. Looking further in the log file, I can also find:

dissect_ssl3_hnd_srv_hello can't find cipher suite 0x88

This cipher suite is indeed missing from the cipher_suites structure defined in epan/dissectors/packet-ssl-utils.c. After studying RFC 5932 - Camellia Cipher Suites for TLS, I found the required parameters for a CipherSuite. The resulting patch should then be submitted to Wireshark as I did here: https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9144. The stable 1.12 series have vastly improved cipher suite and TLS support, so you should not have to manually patch it now.

arunppsg
  • 103
  • 3
Lekensteyn
  • 5,898
  • 5
  • 37
  • 62
  • 1
    "*As the private DH key is not transmitted on the wire nor written to disk*" It seems that for debugging purposes some browsers offer the possibility to write the keys on disk. A [discussion on this subject is available here](http://security.stackexchange.com/q/107306/32746), with the [link to the SAN's original paper](https://isc.sans.edu/forums/diary/Psst+Your+Browser+Knows+All+Your+Secrets/16415). – WhiteWinterWolf Jan 12 '16 at 10:24
  • @WhiteWinterWolf The key is *normally* not written to disk, but if you enable the debugging option it will (that's why I removed it in the edit). See [my reply](http://security.stackexchange.com/a/110420/2630) to that discussion for why I am not conviced that this is a problem. – Lekensteyn Jan 12 '16 at 21:12
  • 1
    A note for `tshark`: `ssl.keylog_file:` worked for me rather than `-o ssl.key_logfile:` as specified above (note the underscore). It's a minor thing but had me stuck for a bit. – vasilyrud Jul 19 '18 at 02:45
  • Additionally if sessions are not being decrypted - check that you have **captured the whole TLS handshake for this session** (i.e ensure you see the "Certificate" message from the server). – user30473 Oct 28 '19 at 17:23
  • 2
    The GUI settings are now under `Protocols->TLS` where one can also configure the location of the debug file. – user30473 Jan 11 '21 at 15:27
9

If you can "expose the premaster secret", though the key exchange uses ephemeral Diffie-Hellman, then you have privileged access to either the client or the server. That's one of the points of DHE: the actual key exchange uses newly generated DH key pairs, which neither client or server stores anywhere except in its own RAM. Having a copy of the permanent server's key would give you nothing, as a passive attacker with Wireshark, since it is used only for signatures. That key could be used to impersonate the server, and thus mount an active Man-in-the-Middle attack.

However you put it, if you have access to the premaster secret, then you should also have direct access to the clear data, without having to resort to crude packet capture; therefore, your question is weird.

Anyway, subsequent data records can be decrypted by following the standard (or one of the previous versions, when applicable), which is an interesting programming exercise. It is possible that ssldump's source code might be reused for that task.

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • 1
    Yes I'm having access to the client. I can find out the application data from the client logs still I want to see the decrypted packets in wireshark for some debugging purpose. But wireshark is supporting RSA only it seems.For DHE any plugins are there.If we provide the session keys or master secret any ways to decrypt it? – Kalai May 10 '13 at 10:17
  • I am not aware of any such plugin, and I presume there is none, because the scenario is unusual; "(pre)master secrets" are normally hidden deep within the SSL implementation. You will probably have to develop that plugin yourself. – Thomas Pornin May 10 '13 at 11:05
  • 1
    If all you really want is to see the raw content consider using an SSL proxy and have the session proxy through it - since you control the client this should be easy. The net result will be that you can ignore all the crypto stuff and just tap the SSL connection at the (local on client) proxy. – Ram May 11 '13 at 18:26
  • 1
    Thanks for the suggestion. I am able to decrypt the packets by using Keylog file in the latest wireshark... – Kalai May 17 '13 at 05:26