Industrial protocols are moving to TLS encryption. Modbus/TCP Security uses port 802. IEC 60870-5-104 over TLS uses port 19998. IEC 61850 MMS over TLS uses port 3782. OPC UA encrypts at the application layer.
When encryption is enabled, Wireshark shows “Application Data” instead of decoded protocol fields. You can see that packets are flowing, but you cannot read function codes, register values, ASDU types, or MMS objects.
This does not mean Wireshark is useless. If you have access to the TLS session keys, Wireshark decrypts the traffic and shows the industrial protocol inside — exactly as if it were unencrypted.
This guide explains how to decrypt each TLS-based industrial protocol in Wireshark, step by step.
In This Guide
1. Why Industrial Protocols Are Moving to TLS
Traditional industrial protocols — Modbus TCP, IEC 104, IEC 61850 MMS — were designed without any security. Data flows in plain text. Any device on the network can read register values, inject commands, or modify packets.
IEC 62351 is the standard that defines how to add security to power system communication protocols. For TCP-based protocols, IEC 62351-3 specifies TLS 1.2 or later with X.509 certificate authentication.
The result: the same industrial protocol runs inside an encrypted TLS tunnel. The protocol itself does not change — only the transport is encrypted.
2. Which Protocols Use TLS and on Which Ports
| Protocol | Standard Port | TLS Port | Security Standard | TLS Version |
|---|---|---|---|---|
| Modbus TCP | 502 | 802 | Modbus/TCP Security (Modbus Organization) | TLS 1.2+ |
| IEC 60870-5-104 | 2404 | 19998 | IEC 62351-3 | TLS 1.2+ |
| IEC 61850 MMS | 102 | 3782 | IEC 62351-3 | TLS 1.2+ |
| OPC UA Binary | 4840 | 4840 (same port) | OPC UA Security (IEC 62541) | Application-layer encryption (not TLS) or TLS for HTTPS transport |
| MQTT | 1883 | 8883 | MQTT over TLS | TLS 1.2+ |
Port 802 is registered with IANA as “mbap-s” (Modbus Application Protocol — Secure). Port 19998 is the standard secure port for IEC 104. Port 3782 is registered as “iso-tp0s” (Secure ISO TP0) for IEC 61850 MMS over TLS.
OPC UA is different — it can use its own application-layer encryption (OPC UA Secure Channel) without TLS, or it can use TLS when running over HTTPS. Wireshark 4.3+ supports OPC UA key logging for application-layer decryption.
3. What You See in Wireshark Without Decryption
When TLS encryption is active, Wireshark shows:
- TCP handshake (SYN, SYN-ACK, ACK) — visible, unencrypted
- TLS Client Hello — visible. Shows the TLS version, cipher suites offered, and SNI (server name)
- TLS Server Hello — visible. Shows the selected cipher suite and the server certificate
- TLS Certificate — visible. You can inspect the X.509 certificate (subject, issuer, expiry)
- Application Data — encrypted. This is where the industrial protocol payload is. You cannot read it.
You can still see:
- Source and destination IP addresses
- Source and destination ports
- Packet sizes and timing
- TLS version and cipher suite
- Certificate details
But you cannot see function codes, register values, ASDU types, MMS objects, or any protocol-level data.
4. The Two Decryption Methods
| Method | How It Works | Works With TLS 1.3 | Works With (EC)DHE | Recommended |
|---|---|---|---|---|
| SSLKEYLOGFILE | Application writes per-session secrets to a file. Wireshark reads the file. | Yes | Yes | Yes — works in all cases |
| RSA Private Key | You provide the server’s RSA private key. Wireshark derives the session key. | No | No | No — only works with RSA key exchange (rare today) |
The SSLKEYLOGFILE method is the only reliable option. Modern TLS uses (EC)DHE (Diffie-Hellman Ephemeral) key exchange, which means the RSA private key alone cannot decrypt the traffic. The session keys are needed.
5. Method 1: SSLKEYLOGFILE (Recommended)
The SSLKEYLOGFILE is a text file where the TLS library writes the per-session encryption keys during the TLS handshake. Wireshark reads this file and uses the keys to decrypt the captured traffic.
How It Works
- Set the
SSLKEYLOGFILEenvironment variable on the machine running the TLS client or server - The application’s TLS library (OpenSSL, NSS, etc.) writes session keys to that file
- Capture traffic with Wireshark
- Point Wireshark to the key log file
- Wireshark decrypts the TLS layer and shows the industrial protocol inside
Setting the Environment Variable
Linux:
bash
export SSLKEYLOGFILE=/home/user/keylog.txt
Add this to ~/.bashrc to make it permanent. Then start your SCADA application from the same terminal.
Windows (Command Prompt):
set SSLKEYLOGFILE=C:\Users\operator\Desktop\keylog.txt
Then start your SCADA application from the same command prompt.
Windows (Permanent):
System Properties → Advanced → Environment Variables → New User Variable → Name: SSLKEYLOGFILE, Value: C:\Users\operator\Desktop\keylog.txt
Which Applications Support SSLKEYLOGFILE
| TLS Library | Supports SSLKEYLOGFILE | Used By |
|---|---|---|
| OpenSSL 1.1.1+ | Yes | Most Linux-based SCADA servers, libiec61850, open62541 |
| OpenSSL 3.4+ | Yes (built-in, no code changes needed) | Newer applications |
| NSS | Yes | Firefox, some Linux applications |
| GnuTLS | Yes | Some Linux applications |
| Java JSSE | No (needs jSSLKeyLog agent) | Java-based SCADA systems |
| .NET SslStream | No (needs workaround) | Some Windows SCADA systems |
| Unified Automation SDK | Yes (since HPSDK 1.8.0) | OPC UA applications |
⚠️ Important: Most embedded industrial devices (PLCs, relays, RTUs, energy meters) do NOT support SSLKEYLOGFILE. The key log method works only when you control the software on the SCADA server, engineering workstation, or gateway — not on the field device itself.
6. Method 2: RSA Private Key (Limited)
If you have the server’s RSA private key and the TLS connection uses RSA key exchange (not DHE/ECDHE), you can provide the key to Wireshark.
In Wireshark: Edit → Preferences → Protocols → TLS → RSA keys list → Edit
Add an entry:
| Field | Value |
|---|---|
| IP address | Server IP (e.g., 192.168.1.100) |
| Port | Server port (e.g., 802) |
| Protocol | The protocol name (e.g., mbtcp) |
| Key File | Path to the server’s private key (.pem or .key) |
This method fails if:
- The cipher suite uses (EC)DHE (which is the default in TLS 1.2 and mandatory in TLS 1.3)
- The session was resumed (session ticket or session ID)
- You do not have the server’s private key
For these reasons, the SSLKEYLOGFILE method is always preferred.
7. Configuring Wireshark for TLS Decryption
Step 1. Open TLS Preferences
Edit → Preferences → Protocols → TLS
Step 2. Set the Key Log File
In the (Pre)-Master-Secret log filename field, browse to your SSLKEYLOGFILE.
Step 3. Enable TCP Reassembly
Make sure these options are enabled (they are by default):
- Edit → Preferences → Protocols → TCP → Allow subdissector to reassemble TCP streams ✅
- Edit → Preferences → Protocols → TCP → Reassemble out-of-order segments ✅
Step 4. Reload the Capture
If you already captured the traffic, close and reopen the capture file. Wireshark applies the key log file on load.
Step 5. Verify Decryption
After loading the key file, encrypted packets that previously showed “Application Data” should now show the decoded industrial protocol (Modbus, IEC 104, MMS, etc.).
If the “Decrypted TLS” tab appears at the bottom of the packet bytes pane, decryption is working.
8. Decrypting Modbus/TCP Security (Port 802)
Modbus/TCP Security wraps standard Modbus TCP frames inside a TLS tunnel on port 802.
Capture
tcp port 802
After Decryption
Once the TLS layer is decrypted, Wireshark may not automatically decode the payload as Modbus. You need to tell it:
- Right-click a decrypted packet → Decode As…
- Set: Field = TLS port, Value = 802, Current = MBTCP
- Click OK
Now you will see standard Modbus TCP fields: Transaction ID, Unit ID, Function Code, register addresses, and data values — exactly as on port 502.
Display Filter
modbus && tcp.port == 802
9. Decrypting IEC 60870-5-104 over TLS (Port 19998)
IEC 62351-3 adds TLS encryption to IEC 104 communication on port 19998.
Capture
tcp port 19998
After Decryption
After TLS decryption, Wireshark may need a “Decode As” step:
- Right-click a decrypted packet → Decode As…
- Set: Field = TLS port, Value = 19998, Current = IEC 60870-5-104
- Click OK
You will see the standard IEC 104 APCI and ASDU structure: I-format, S-format, U-format frames, type IDs, information objects, and quality descriptors.
Display Filter
iec60870_104 && tcp.port == 19998
10. Decrypting IEC 61850 MMS over TLS (Port 3782)
IEC 62351-3 adds TLS to MMS communication on port 3782 (registered as “iso-tp0s”).
Capture
tcp port 3782
After Decryption
After TLS decryption, you need to decode the inner protocol stack:
- Right-click a decrypted packet → Decode As…
- Set: Field = TLS port, Value = 3782, Current = TPKT
- Click OK
This tells Wireshark to decode the decrypted payload as TPKT → COTP → Session → Presentation → MMS — the same stack as on port 102.
If MMS still does not decode, configure the PRES context manually as described in the Wireshark IEC 61850 MMS guide.
Display Filter
mms && tcp.port == 3782
11. Decrypting OPC UA Secure Channel
OPC UA is different from the other protocols. It can encrypt at the application layer using its own Secure Channel mechanism (not TLS). This means the SSLKEYLOGFILE method does not work for OPC UA Binary encrypted with Secure Channel.
Wireshark 4.3+ Solution
Since Wireshark 4.3, the OPC UA dissector supports OPC UA key logging. The OPC UA application writes session keys to a key log file, and Wireshark uses them to decrypt.
This is supported by:
- Unified Automation High Performance SDK (v1.8.0+)
- Unified Automation C++ SDK
- UaExpert (Unified Automation’s OPC UA client)
Setup
- Enable key logging in your OPC UA application (check the SDK documentation)
- The application writes keys to a file
- In Wireshark: Edit → Preferences → Protocols → OpcUa → Key log file → point to the file
- Capture and decode
OPC UA over HTTPS
If OPC UA uses HTTPS transport (instead of OPC UA Binary), standard TLS decryption with SSLKEYLOGFILE works — the same as any HTTPS connection.
12. What You Can Still Learn Without Decryption
Even when you cannot decrypt the traffic, Wireshark still shows useful information:
| What You Can See | Why It Helps |
|---|---|
| IP addresses and ports | Verify which devices are communicating and on which ports |
| TCP handshake timing | Measure connection setup time |
| TLS Client Hello / Server Hello | See TLS version, cipher suite, and supported extensions |
| Server certificate | Verify certificate subject, issuer, expiry date, and trust chain |
| Packet sizes | Estimate data volume and detect anomalies |
| Packet timing | Measure response times, detect timeouts and retransmissions |
| TCP RST / FIN | Detect connection drops and their cause |
| TLS alerts | See TLS-level errors (certificate expired, handshake failure, etc.) |
| Connection count | Count how many TLS sessions are active |
Useful Filters for Encrypted Traffic
| Filter | What It Shows |
|---|---|
tls | All TLS traffic |
tls.handshake | TLS handshake messages only |
tls.handshake.type == 1 | Client Hello messages |
tls.handshake.type == 2 | Server Hello messages |
tls.handshake.type == 11 | Certificate messages |
tls.alert_message | TLS alert messages (errors) |
tls.record.version == 0x0303 | TLS 1.2 traffic |
tls.handshake.ciphersuite | Filter by specific cipher suite |
tcp.port == 802 | Modbus/TCP Security traffic |
tcp.port == 19998 | IEC 104 over TLS traffic |
tcp.port == 3782 | IEC 61850 MMS over TLS traffic |
13. Limitations and Practical Considerations
You Cannot Decrypt Traffic from Devices You Do Not Control
The SSLKEYLOGFILE method requires you to set an environment variable on the machine running the TLS client or server. If the encrypted traffic originates from an embedded device (relay, RTU, PLC, meter) that you cannot modify, you cannot extract the session keys.
In that case, your options are:
- Capture on the SCADA server side where you can set the environment variable
- Use a TLS-terminating proxy (e.g., mitmproxy with SSLKEYLOGFILE) between the SCADA server and the network
- Temporarily disable encryption for troubleshooting (only in test environments, never in production)
Key Log Files Are a Security Risk
The SSLKEYLOGFILE contains the keys needed to decrypt all captured TLS sessions. Anyone with both the capture file and the key log file can read the decrypted traffic.
- Delete the key log file after troubleshooting
- Never leave SSLKEYLOGFILE enabled in production
- Store key log files with the same security as private keys
Not All SCADA Software Supports Key Logging
Many commercial SCADA systems use proprietary TLS implementations or Java-based TLS (JSSE) that do not support the SSLKEYLOGFILE environment variable. Check with your SCADA vendor.
Open-source libraries like OpenSSL and libiec61850 generally support it. Commercial products vary.
Summary
TLS encryption protects industrial protocols from eavesdropping and tampering. But when you need to troubleshoot, you can still decrypt the traffic in Wireshark — if you have the TLS session keys.
The key things to remember:
- SSLKEYLOGFILE is the only reliable decryption method for modern TLS (1.2 with DHE/ECDHE and TLS 1.3)
- Set the environment variable on the SCADA server or client where you control the software
- After decryption, use Decode As to tell Wireshark which industrial protocol is inside the TLS tunnel
- Port 802 = Modbus/TCP Security, Port 19998 = IEC 104 over TLS, Port 3782 = MMS over TLS
- OPC UA uses application-layer encryption — Wireshark 4.3+ supports OPC UA key logging
- Even without decryption, Wireshark shows TCP timing, TLS handshake details, certificates, and connection patterns
