{"id":390,"date":"2025-03-02T00:36:52","date_gmt":"2025-03-01T21:36:52","guid":{"rendered":"https:\/\/www.nicau.ro\/?p=390"},"modified":"2025-03-03T17:20:42","modified_gmt":"2025-03-03T14:20:42","slug":"inspecting-tls-traffic","status":"publish","type":"post","link":"https:\/\/www.nicau.ro\/?p=390","title":{"rendered":"Inspecting TLS traffic"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><a href=\"https:\/\/www.nicau.ro\/wp-content\/uploads\/2025\/03\/time.png\"><img loading=\"lazy\" src=\"https:\/\/www.nicau.ro\/wp-content\/uploads\/2025\/03\/time-1024x990.png\" alt=\"\" class=\"wp-image-391\" width=\"256\" height=\"248\" srcset=\"https:\/\/www.nicau.ro\/wp-content\/uploads\/2025\/03\/time-1024x990.png 1024w, https:\/\/www.nicau.ro\/wp-content\/uploads\/2025\/03\/time-300x290.png 300w, https:\/\/www.nicau.ro\/wp-content\/uploads\/2025\/03\/time-768x743.png 768w, https:\/\/www.nicau.ro\/wp-content\/uploads\/2025\/03\/time-1536x1485.png 1536w, https:\/\/www.nicau.ro\/wp-content\/uploads\/2025\/03\/time-624x603.png 624w, https:\/\/www.nicau.ro\/wp-content\/uploads\/2025\/03\/time.png 1630w\" sizes=\"(max-width: 256px) 100vw, 256px\" \/><\/a><\/figure><\/div>\n\n\n\n<p class=\"has-medium-font-size\">TLS traffic with Chrome and Wireshark<\/p>\n\n\n\n<p>TLS traffic inspection on Ubuntu\/Wireshark can be easily configured. For each TLS handshake the encryption keys need to be made available at the middle man. For this to run automatically we need two things: 1) activate the dumping of the (pre)master-secret and 2) Wireshark needs to know where to look.<\/p>\n\n\n\n<p>Following steps have been tested on Ubuntu Noble Numbat 24.04, Google Chrome 133.0.6943.141(official build)(64-bit) and Wireshark 4.2.2:<\/p>\n\n\n\n<ul><li>add SSLKEYLOGFILE to the environment and start Chrome: <strong>export SSLKEYLOGFILE=\/home\/hiddenuser\/.ssl-key.log &amp;&amp; google-chrome<\/strong><\/li><li>browse to some https:\/\/ URL and verify the keylog file is being updated<\/li><li>in Wireshark at the Edit-&gt;Preferences-&gt;Protocols-&gt;TLS under the (Pre)-Master-Secret log filename, use the above file &#8220;\/home\/hiddenuser\/.ssl-key.log&#8221;<\/li><li>generate traffic and inspect it by adding to Wireshark a general filter &#8220;tls &amp;&amp; (http || http2)&#8221;<\/li><\/ul>\n\n\n\n<div class=\"wp-block-group has-black-color has-text-color\"><div class=\"wp-block-group__inner-container\">\n<p><\/p>\n\n\n\n<p class=\"has-medium-font-size\">TLS Keylog File<\/p>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container\">\n<p>The .ssl-key.log file format &#8211; each line contains a separate secret composed of 3 values:<\/p>\n\n\n\n<ul><li>the label<ul><li>identifies the type of secret<\/li><li>there can be multiple types, for ex: CLIENT_RANDOM, CLIENT_HANDSHAKE_TRAFFIC_SECRET, SERVER_HANDSHAKE_TRAFFIC_SECRET, CLIENT_TRAFFIC_SECRET_0, SERVER_TRAFFIC_SECRET_0, etc<\/li><\/ul><\/li><li>client random<ul><li>the string of random bytes generated on the client during the <code>Client Hello<\/code> part of the TLS handshake protocol<\/li><li>this is a 32 byte value represented as 64 hexa chars<\/li><li>is used as a key in order to differentiate which labels belong to which connection<\/li><\/ul><\/li><li>secret<ul><li>variable length hex value<\/li><\/ul><\/li><\/ul>\n<\/div><\/div>\n\n\n\n<p>As example take a look at this section from my .ssl-key.log where we can observe entries from three independent negociations:<\/p>\n\n\n\n<p style=\"font-size:8px\"><strong>CLIENT_TRAFFIC_SECRET_0 <\/strong>a32eb0704df85d2c8dfed2ecf721ed512d33da179732965c721dc4ba935e53f5 cdf1b007b92e8aa77da7091cb81f0fd75132c83eab85865bb6a76432cc9f959ab4712636271f506665b1dfd97a1f8ce8<br><strong>SERVER_TRAFFIC_SECRET_0 <\/strong>a32eb0704df85d2c8dfed2ecf721ed512d33da179732965c721dc4ba935e53f5 0c1e810216b76f388aa9179b852fa2b1f935c2224f082d51801118362e28567199ea7802446ce9e9d802042f2a95a6d0<br><strong>EXPORTER_SECRET <\/strong>a32eb0704df85d2c8dfed2ecf721ed512d33da179732965c721dc4ba935e53f5 45db7b3bc67a4c700863cb9dce62d38329239db3eade797ea8e990065bda14e6fdf1e2768bc5be2ff78fef916e74bcb0<br><strong>CLIENT_HANDSHAKE_TRAFFIC_SECRET <\/strong>ed0a238a60e290cb3864a899818b496f4de2bc4d8f9489e90e047ec9b9e6465c cf668ae741f57c7c42d44d35a1d71c0ce888f947de3056741cf394cf7ccd919e9c36574ca20c76f9cd6db9f709943702<br><strong>SERVER_HANDSHAKE_TRAFFIC_SECRET <\/strong>ed0a238a60e290cb3864a899818b496f4de2bc4d8f9489e90e047ec9b9e6465c 2a093a96dc61bca91d9710444202d471f7175ee427242e2e572f186dfdd8f4096fa9c6a77a4dfdb2806ce609267310c8<br><strong>CLIENT_RANDOM <\/strong>c382a546c4c5f47961c208aefc57dfce8d09c1ba8d23ab2b297a269d961bc816 2ec13a3622f4c60fba03f565f6bd701a3765582b1344879ae25a978b316cd4c04b1ae0547b1b9f239781659695d6d0a8<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p class=\"has-medium-font-size\">TLS pre-master secret vs master secret<\/p>\n\n\n\n<p>To establish a fully encrypted communication over <strong>TLS 1.2<\/strong> here are the steps involved. Please note the role of the pre-master secret:<\/p>\n\n\n\n<ul><li>Client Hello &#8211; sends supported TLS version, supported ciphers, a client random string<\/li><li>Server Hello &#8211; sends server&#8217;s SSL certificate, server chosen cipher, a server random string<\/li><li>Authentication &#8211; client verifies server&#8217;s SSL certificate with the CA that issued it<\/li><li>Server Hello Done &#8211; sends a message to client to confirm that Server Hello has been completed<\/li><li>Client Key Exchange &#8211; client generates a <em>pre-master secret<\/em>, another random string. this is encrypted using the public key embedded in the received SSL certificate and is sent to the server<\/li><li>Private key used &#8211; server decrypts the pre-master secret using its private key<\/li><li>Session keys created &#8211; both client and server generate independently session keys from the: client random str, server random str and the pre-master secret. both should be the same<\/li><li>Client Ready &#8211; client sends a &#8220;finished&#8221; message encrypted with a session key<\/li><li>Server Ready &#8211; server sends a &#8220;finished&#8221; message encrypted with a session key<\/li><li>Handshake Finished &#8211; communication goes on with a symmetric encryption<\/li><\/ul>\n\n\n\n<p>So the all wanted <em>pre-master secret<\/em> is a random string generated on the client, shared with the server and lastly used to generate the master secret on both ends.<\/p>\n\n\n\n<p>A Pseudo-Random Function (PRF) is then employed to calculate the master_secret = PRF(pre-master-secret, &#8220;Master-Secret&#8221;, ClientHello.random + ServerHello.random). In the end the master_secret is used on the client and on the server to generate the session key.<\/p>\n\n\n\n<p>Having described the steps for the old TLS 1.2, with <strong>TLS 1.3<\/strong> which nowdays is almost ubiquous, we can see the process is simplified \/ accelerated. Based on the info received during the Client Hello &#8211; a client random string and a client key share, the server generates the pre-master secret and even advances generating the master secret. During the Server Hello, the server sends back the server random string along with a server key share. This data is sufficient for the client to independently generate the pre-master secret &#8211; which as you see is not that random anymore, and will advance to generating the master secret. Such method works because each party agrees and openly shares a set of parameters along with a public key &#8211; carefully crafted using the aforementioned params &#8211; see the Diffie\u2013Hellman key exchange and the Elliptic-curve Diffie\u2013Hellman.<\/p>\n\n\n\n<p>Depending on the TLS version running, entries in the .ssl-key.log might contain either the pre-master secret or the master secret. For ex. in case of TLS 1.2 the CLIENT_RANDOM type is used to identify the &#8220;master&#8221; secret for the connection.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p class=\"has-medium-font-size\">References<\/p>\n\n\n\n<p><a href=\"https:\/\/wiki.wireshark.org\/TLS#using-the-pre-master-secret\">https:\/\/wiki.wireshark.org\/TLS#using-the-pre-master-secret<\/a><br><a href=\"https:\/\/datatracker.ietf.org\/doc\/html\/draft-ietf-tls-keylogfile\">https:\/\/datatracker.ietf.org\/doc\/html\/draft-ietf-tls-keylogfile<\/a><br><a href=\"https:\/\/medium.com\/@thesslstore\/tls-1-3-handshake-taking-a-closer-look-11667ff92645\">https:\/\/medium.com\/@thesslstore\/tls-1-3-handshake-taking-a-closer-look-11667ff92645<\/a><br><a href=\"https:\/\/www.cryptologie.net\/article\/340\/tls-pre-master-secrets-and-master-secrets\">https:\/\/www.cryptologie.net\/article\/340\/tls-pre-master-secrets-and-master-secrets<\/a><br><a href=\"https:\/\/cabulous.medium.com\/tls-1-2-andtls-1-3-handshake-walkthrough-4cfd0a798164\">https:\/\/cabulous.medium.com\/tls-1-2-andtls-1-3-handshake-walkthrough-4cfd0a798164<\/a><br><a href=\"https:\/\/en.wikipedia.org\/wiki\/Elliptic-curve_Diffie%E2%80%93Hellman\">https:\/\/en.wikipedia.org\/wiki\/Elliptic-curve_Diffie%E2%80%93Hellman<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>TLS traffic with Chrome and Wireshark TLS traffic inspection on Ubuntu\/Wireshark can be easily configured. For each TLS handshake the encryption keys need to be made available at the middle man. For this to run automatically we need two things: 1) activate the dumping of the (pre)master-secret and 2) Wireshark needs to know where to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[23],"tags":[20,22,21],"_links":{"self":[{"href":"https:\/\/www.nicau.ro\/index.php?rest_route=\/wp\/v2\/posts\/390"}],"collection":[{"href":"https:\/\/www.nicau.ro\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.nicau.ro\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.nicau.ro\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.nicau.ro\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=390"}],"version-history":[{"count":11,"href":"https:\/\/www.nicau.ro\/index.php?rest_route=\/wp\/v2\/posts\/390\/revisions"}],"predecessor-version":[{"id":404,"href":"https:\/\/www.nicau.ro\/index.php?rest_route=\/wp\/v2\/posts\/390\/revisions\/404"}],"wp:attachment":[{"href":"https:\/\/www.nicau.ro\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=390"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.nicau.ro\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=390"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.nicau.ro\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=390"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}