Sign up ×
Information Security Stack Exchange is a question and answer site for information security professionals. It's 100% free, no registration required.

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?

share|improve this question

migrated from May 9 '13 at 15:08

This question came from our site for software developers, mathematicians and others interested in cryptography.

2 Answers 2

Some background: Wireshark supports decryption of SSL sessions when you provide the private RSA key of the server. This works for cipher suites using a RSA key exchange where the pre-master secret is encrypted using the RSA public key of the server. For ephemeral Diffie-Hellman (DHE) cipher suites, the RSA public key is only used for signing the DH parameters which are generated during the handshake. As the private DH key is not transmitted on the wire nor written to disk and the public RSA key is only used for signing, you cannot decrypt traffic by just having the private RSA key.

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 key log 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)
    • The Session ID field of a Server Hello handshake message. (RSA Session-ID:XXX YYY, since Wireshark 1.6.0)
    • The Session Ticket in a Client Hello TLS extension or Session Ticket handshake message. (RSA Session-ID:XXX 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

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.

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.key_logfile: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 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: The stable 1.12 series have vastly improved cipher suite and TLS support, so you should not have to manually patch it now.

There is pretty scare documentation on this, this should help you to get your cipher faster supported:

typedef struct _SslCipherSuite {
    gint number;
    gint kex;
    gint sig;
    gint enc;
    gint block; /* size of IV block for CBC and GCM */
    gint bits; /* size of key in bits */
    gint eff_bits; /* equal to bits, or lower for export cipher */
    gint dig; /* DIG_SHA, DIG_SHA256, etc. */

    /* the following two are removed in 1.11.0 because they are redundant */
    gint dig_len; /* 20, 40, etc. (must match dig!) */
    gint export_cipher;

    gint mode; /* SSL_CIPHER_MODE_{CBC,STREAM}, depends on cipher */
} SslCipherSuite;

While developing, it may be useful to generate some packets. For that purpose, see have a look at the openssl-connect and openssl-listen shell scripts on (there are also some other miscellaneous scripts in there).

share|improve this answer

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.

share|improve this answer
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
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
Thanks for the suggestion. I am able to decrypt the packets by using Keylog file in the latest wireshark... – Kalai May 17 '13 at 5:26

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.