diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index db38582f4..af7ba3c94 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -41,3 +41,11 @@ The tests always log to the console. See the [Logging documentation](https://ssh
 ### Wireshark
 
 Wireshark is able to dissect initial connection packets, such as key exchange, before encryption happens. Enter "ssh" as the display filter. See https://wiki.wireshark.org/SSH.md for more information.
+
+The Debug build of SSH.NET has helpers to also allow dissection of the encrypted traffic by dumping the session keys in a format that Wireshark understands. Set a value for `SshNetLoggingConfiguration.WiresharkKeyLogFilePath` before connecting, and supply the same value to Wireshark in Edit -> Preferences -> Protocols -> SSH -> "Key log filename".
+
+```c#
+using Renci.SshNet;
+
+SshNetLoggingConfiguration.WiresharkKeyLogFilePath = @"C:\tmp\sshkeylogfile.txt";
+```
diff --git a/src/Renci.SshNet/Session.cs b/src/Renci.SshNet/Session.cs
index c5356db8e..800c0d5df 100644
--- a/src/Renci.SshNet/Session.cs
+++ b/src/Renci.SshNet/Session.cs
@@ -320,7 +320,7 @@ private set
         /// Gets the client init message.
         /// 
         /// The client init message.
-        public Message ClientInitMessage { get; private set; }
+        public KeyExchangeInitMessage ClientInitMessage { get; private set; }
 
         /// 
         /// Gets the server version string.
@@ -1582,6 +1582,16 @@ internal void OnNewKeysReceived(NewKeysMessage message)
             _clientCompression = _keyExchange.CreateCompressor();
             _serverDecompression = _keyExchange.CreateDecompressor();
 
+#if DEBUG
+            if (SshNetLoggingConfiguration.WiresharkKeyLogFilePath is string path
+                && _keyExchange is KeyExchange kex)
+            {
+                System.IO.File.AppendAllText(
+                    path,
+                    $"{ToHex(ClientInitMessage.Cookie)} SHARED_SECRET {ToHex(kex.SharedKey)}{Environment.NewLine}");
+            }
+#endif
+
             // Dispose of old KeyExchange object as it is no longer needed.
             _keyExchange.HostKeyReceived -= KeyExchange_HostKeyReceived;
             _keyExchange.Dispose();
diff --git a/src/Renci.SshNet/SshNetLoggingConfiguration.cs b/src/Renci.SshNet/SshNetLoggingConfiguration.cs
index 4add75c9f..fa8581b3b 100644
--- a/src/Renci.SshNet/SshNetLoggingConfiguration.cs
+++ b/src/Renci.SshNet/SshNetLoggingConfiguration.cs
@@ -22,5 +22,17 @@ public static void InitializeLogging(ILoggerFactory loggerFactory)
             ThrowHelper.ThrowIfNull(loggerFactory);
             LoggerFactory = loggerFactory;
         }
+
+#if DEBUG
+        /// 
+        /// Gets or sets the path to which to write session secrets which
+        /// Wireshark can read and use to inspect encrypted traffic.
+        /// 
+        /// 
+        /// To configure in Wireshark, go to Edit -> Preferences -> Protocols
+        /// -> SSH and set the same value for "Key log filename".
+        /// 
+        public static string? WiresharkKeyLogFilePath { get; set; }
+#endif
     }
 }