跳到主要内容

加密配置

只覆盖实操步骤. OPC UA 加密原理见 OPC UA 安全概念.

配套阅读

1. SecurityMode 选哪个

场景Mode
内网开发联调None
内网生产Sign + Username
公网 / 跨厂区SignAndEncrypt + Username 或 Certificate

SecurityPolicy 固定用 Basic256Sha256 (SDK 不支持已废弃的 Basic128Rsa15 / Basic256).

2. 生成客户端证书 (PFX)

任选其一即可.

OpenSSL (跨平台通用):

openssl req -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes \
-subj "/CN=MyClient/O=Darra/C=CN" \
-addext "subjectAltName=URI:urn:my-company:my-client,DNS:my-host"
openssl pkcs12 -export -out client.pfx -inkey key.pem -in cert.pem -password pass:123456
openssl x509 -in cert.pem -outform DER -out cert.der # 公钥, 拷给服务端

SDK 内代码生成:

CertificateManager.GenerateSelfSigned(
outPath: "client.pfx", password: "123456",
commonName: "MyClient",
applicationUri: "urn:my-company:my-client",
validDays: 365);
ApplicationUri 必须 = SAN URI

SAN URI 必须设置, 且后续 ApplicationUri 必须与之完全一致, 否则 BadCertificateUriInvalid.

3. SDK 中传入证书

using var ua = new DarraOpcUa("opc.tcp://server:4840",
securityMode: MessageSecurityMode.SignAndEncrypt,
securityPolicyUri: "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256",
clientCertPath: @"C:\certs\client.pfx",
clientKeyPath: "123456"); // PFX 密码 (字段名复用 client_key_path)
ua.Connect();

4. 互信

服务端信任客户端: 把客户端 .der 公钥拷到 server 的 trusted 目录.

Server路径
Darra SimulatorServer<sim>/pki/trusted/certs/
open62541 example<server>/pki/trusted/certs/
UaExpert设置 → Certificates → Trust this certificate

客户端信任服务端 — 推荐 TOFU (首次连接保存指纹, 之后校验一致):

serverCertPath: null     // null = TOFU

如需固定校验, 改为 serverCertPath: @"C:\trusted\server.der".

5. 常见错误

错误原因解决
BadCertificateUriInvalidSAN URI ≠ ApplicationUri重新生成证书时确保两者一致
BadCertificateUntrusted服务端未信任客户端把客户端 .der 拷进服务端 pki/trusted/certs/
BadCertificateHostNameInvalid连接 host 与证书 SAN.DNS 不匹配用 IP 连或证书加 DNS SAN
BadCertificateTimeInvalid客户端 / 服务端时间偏差大NTP 同步: w32tm /resynctimedatectl set-ntp true
BadSecurityPolicyRejected服务端未开 Basic256Sha256服务端配置开启该 Policy

诊断证书内容:

var info = CertificateManager.Inspect("client.pfx", "123456");
Console.WriteLine($"SAN URI: {info.SubjectAltNameUri}");
Console.WriteLine($"Valid: {info.NotBefore} ~ {info.NotAfter}");

相关链接