3、OPC UA安全策略配置:安全策略选择、消息签名与加密、用户认证模式

好,咱们进入第三章。说实话,安全策略配置这块,是很多OPC UA项目里最容易出问题的地方。我见过不少项目,安全策略配得乱七八糟,要么是根本连不上,要么是裸奔上阵。今天咱们就把这事儿掰扯清楚。

3.1 安全策略选择:Basic256Sha256 为什么是首选?

OPC UA 规范里定义了好几种安全策略,但实际项目中常用的就那么几个。我列个表,你一看就明白。

安全策略 对称加密算法 签名算法 密钥长度 推荐场景
None 无 无 N/A 仅测试环境
Basic128Rsa15 AES-128 RSA-SHA1 128位 遗留系统兼容
Basic256 AES-256 RSA-SHA1 256位 已不推荐
Basic256Sha256 AES-256 RSA-SHA256 256位 生产环境首选
Aes128Sha256RsaOaep AES-128 RSA-SHA256 128位 新项目可选
Aes256Sha256RsaPss AES-256 RSA-PSS 256位 最高安全要求

我个人习惯,只要不是跟十年前的旧设备对接,一律选 Basic256Sha256。为什么?

  • 算法够硬:AES-256 加密,RSA-SHA256 签名,目前没有已知的有效攻击。
  • 兼容性好:几乎所有现代 OPC UA SDK 都支持,不像 Aes256Sha256RsaPss 那样挑版本。
  • 性能可接受:在工业控制器上,256位对称加密的开销完全扛得住。
注意:千万别在生产环境用 None 策略。我曾经接手过一个项目,前任工程师为了调试方便,把安全策略设成了 None,结果上线半年都没改回来。后来被安全审计抓了个正着,整个产线被迫停机整改。

3.2 消息签名与加密:到底签什么?加密什么?

很多初学者搞不清楚签名和加密的区别。说白了,签名是防篡改,加密是防偷看。OPC UA 里这两件事是分开配置的。

OPC UA 的消息安全模式有三种:

  • Sign:只签名,不加密。消息内容是明文的,但能检测是否被篡改。
  • SignAndEncrypt:先签名,再加密。既防篡改又防偷看。
  • None:裸奔,啥也不做。

你想想看,在工业现场,控制指令要是被人篡改了,后果有多严重?所以我的建议是:

  • 数据采集场景(读变量、读历史数据):可以用 Sign,性能开销小一些。
  • 控制指令场景(写变量、调用方法):必须用 SignAndEncrypt。
  • 配置变更场景(修改服务器参数):同样必须用 SignAndEncrypt。

核心原则:能加密就加密,能签名就签名。别为了省那点CPU占用,把整个产线暴露在风险里。

3.3 用户认证模式:匿名?用户名?证书?

OPC UA 的用户认证,说白了就是「你是谁」的问题。常见的有三种模式:

认证模式 安全等级 适用场景 管理成本
Anonymous 低 只读数据展示、内部调试 无
UserName/Password 中 操作员站、HMI 低
X.509 Certificate 高 服务器间通信、关键控制 高

嗯,这里要注意一点:匿名不等于不安全。如果你把匿名用户限制为只读权限,配合 SignAndEncrypt 的消息安全模式,其实也能达到不错的安全水平。但如果你让匿名用户能写变量,那就是在给自己挖坑。

用户名密码模式,我建议配合 HTTPS 或 TLS 传输层加密一起用,否则密码在网络上就是明文传输的。我记得有个客户,他们的 OPC UA 服务器跑在办公网里,用的就是用户名密码模式,但没有启用传输层加密。结果 IT 部门做渗透测试时,直接抓包拿到了管理员密码。

证书认证是最安全的,但管理起来也最麻烦。你需要:

  • 搭建 CA(证书颁发机构)
  • 为每个客户端和服务器签发证书
  • 管理证书吊销列表(CRL)
  • 定期轮换证书
我的经验:如果现场只有几十个节点,用用户名密码就够了。如果超过一百个节点,或者涉及跨厂区通信,建议上证书认证。别一开始就上证书,否则运维团队会骂娘的。

3.4 安全策略配置实战:代码示例

下面给一个 C# 的配置示例,用的是 OPC Foundation 的官方 SDK。这段代码我实际项目里改过很多次,基本能直接复用。

// 创建客户端配置
var clientConfig = new ApplicationConfiguration
{
    ApplicationName = "MyOPCUAClient",
    ApplicationType = ApplicationType.Client,
    SecurityConfiguration = new SecurityConfiguration
    {
        // 安全策略:Basic256Sha256
        SelectedSecurityPolicies = new List<string>
        {
            SecurityPolicies.Basic256Sha256
        },
        
        // 消息安全模式:签名+加密
        SelectedMessageSecurityModes = new List<MessageSecurityMode>
        {
            MessageSecurityMode.SignAndEncrypt
        },
        
        // 用户认证:用户名密码
        UserIdentityTokenPolicies = new List<UserTokenPolicy>
        {
            new UserTokenPolicy(UserTokenType.UserName)
        },
        
        // 证书验证选项(生产环境要严格)
        CertificateValidator = new CertificateValidator
        {
            CertificateValidationOptions = CertificateValidationOptions.SuppressCertificateExpired |
                                           CertificateValidationOptions.SuppressCertificateChainNotComplete
        }
    }
};

// 创建会话
var session = await Session.Create(
    clientConfig,
    new ConfiguredEndpoint(null, new Uri("opc.tcp://192.168.1.100:4840")),
    new UserIdentity(new UserNameIdentityToken("admin", "P@ssw0rd")),
    true);
避坑指南:我曾经在生产环境里把 CertificateValidationOptions 设成了 SuppressAll,结果证书过期了都不知道,直到设备离线才发现。生产环境一定要保留基本的证书验证,至少检查过期时间和颁发者。

3.5 安全策略组合决策树

为了让你更直观地理解怎么选,我画了一张决策图。你可以把它贴在工位上,每次配置新设备时对照着看。

OPC UA 安全策略组合决策树 开始配置 通信类型:数据采集 vs 控制指令? 数据采集 控制指令 安全策略:Basic256Sha256 安全策略:Basic256Sha256 消息模式:Sign(性能优先) 消息模式:SignAndEncrypt(必须) 用户认证:Anonymous 或 UserName 用户认证:UserName 或 Certificate 结果:安全等级中高,性能良好 控制指令路径必须启用 SignAndEncrypt + 强用户认证

这张图的核心逻辑很简单:先看通信类型,再选安全策略,最后定用户认证。别跳步骤,也别为了省事选低安全等级。

3.6 常见配置错误与排查

最后,我总结几个我踩过的坑,你遇到了可以直接对照排查:

  • 客户端和服务器安全策略不匹配:两边必须选同一个策略,否则握手失败。检查 Server 端支持的策略列表,客户端只选其中一个。
  • 证书信任链没建立:客户端证书没导入服务器的信任列表,反过来也一样。检查两边的 CertificateStore。
  • 用户认证凭据错误:用户名密码不对,或者证书私钥没权限访问。这个最基础,但也最容易忽略。
  • 消息安全模式不一致:客户端设了 SignAndEncrypt,服务器只支持 Sign。协商失败时会报 Bad_SecurityModeRejected。
排查技巧:先用 OPC UA 的测试工具(比如 UaExpert)连一下服务器,看看它能支持哪些安全策略和用户认证模式。确认了再写代码,能省一半的调试时间。