Concluded·21 Jun 2026 · 2 min read

OPC UA: NoSecurity vs Sign & Encrypt on the wire

OPC UA · asyncua · Basic256Sha256 · Docker · tcpdump · tshark

The capstone measures the difference a securable protocol makes. One server, one variable, two endpoints — one with security off, one with Sign & Encrypt on — and a capture of the same read through both.

Kepware is the usual aggregator in this role and is Windows-only, so this runs on an open OPC UA server (asyncua). The role and the result are what matter.

Lab setup

security/opcua-server.py builds an asyncua server on TCP 4840 that offers two security policies at once:

server.set_security_policy([
    ua.SecurityPolicyType.NoSecurity,
    ua.SecurityPolicyType.Basic256Sha256_SignAndEncrypt,
])

It seeds one variable, Pump.Speed = 42.0, and generates a self-signed certificate for the encrypted endpoint. The client (security/opcua-read.py) generates its own certificate, then reads the variable twice — once through each door.

Reproduce

python opcua-server.py     # NoSecurity + Basic256Sha256 Sign&Encrypt, Pump.Speed=42.0
tcpdump -i br-<id> -w opcua.pcap 'tcp port 4840'
python opcua-read.py       # reads through both endpoints

Client output:

NoSecurity     read Pump.Speed = 42.0   (cleartext on the wire)
Sign&Encrypt   read Pump.Speed = 42.0   (encrypted on the wire)

The proof

Both reads returned 42.0. The IEEE-754 double for 42.0 is 00 00 00 00 00 00 45 40. Counting its occurrences across the whole capture:

opcua-read.py output and a grep showing the value 42.0 appears on the wire exactly once
Both reads returned 42.0, but the value's bytes cross the wire exactly once — the NoSecurity read. The Sign & Encrypt read carried the same answer in an encrypted MSG body.

The capture contains two full sessions (two HELLO/ACK, two OpenSecureChannel pairs, the MSG bodies). Only the NoSecurity session exposes the value; the Sign & Encrypt session's application payload is encrypted.

Door 1 — NoSecurityReadResponse on the wire:Double 42.0 = 00 00 00 00 00 00 45 40readable to anyone on the segmentDoor 2 — Sign & EncryptMSG on the wire:e7 1c a9 f0 … (encrypted body)the man on the wire goes blind42.0 crossed the wire in the clear once, though both reads returned it.
The same read of Pump.Speed = 42.0, through two doors on the same server. The value's IEEE-754 double appears on the wire exactly once in the whole capture — the NoSecurity read. Sign & Encrypt carried the same answer and showed the wire nothing.

The series on one ladder

ProtocolDefend atModbus TCP1979 · serial rootsNetwork — segment & monitorEtherNet/IP · S7commmodern vendor fieldbusNetwork — segment & monitorMQTT · Sparkplugthe UNS layerProtocol — auth · ACL · TLSOPC UAbuilt networkedProtocol — Sign & Encrypt
The whole series on one ladder. The older protocols cannot defend themselves, so you defend the network. The newer ones can, so you turn it on. OPC UA is the top rung: the protocol carries the lock.

Modbus, EtherNet/IP, and S7comm cannot defend themselves, so they are defended at the network. MQTT and OPC UA can, so they are defended at the protocol. The aggregator on the IT/OT boundary is where both halves meet — plaintext down to what cannot do better, Sign & Encrypt up to what can:

ControllersModbus · CIP · S7plaintext southOPC UA aggregatorKepware-class gatewaySign & Encrypt northSCADA · historianreads nothing leaks
An OPC UA aggregator (the role Kepware plays, though Kepware is Windows-only so this ran on an open OPC UA server) sits on the IT/OT boundary. It speaks plaintext down to the controllers that cannot do better, and can speak Sign & Encrypt up to everything that can.

Note on Kepware

Kepware (KEPServerEX) is Windows-only and was not run in this Linux lab; an open OPC UA server stood in for the aggregator role. The security-mode contrast — None readable, Sign & Encrypt opaque — is a property of OPC UA itself, not of any one product.

Harness

opcua-server.py, opcua-read.py, and opcua.pcap are in the modbus-copilot repo security/. Isolated lab, own equipment only.

Why this matters, in plain terms: OPC UA can refuse, and almost nobody asks it to.

Newsletter

New essays, by email.

SCADA, cloud, AI, and the plant floor — a short email when something new is published. No noise, unsubscribe anytime.