You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python连接Basic256Sha256安全策略OPC UA服务器报错求助

解决OPC UA Basic256Sha256安全策略下的Python客户端连接问题

问题诊断

从错误BadSecurityChecksFailed和超时日志来看,核心问题是客户端证书未通过服务器的安全校验——即便你已在服务器信任了test.com证书,仍可能存在以下疏漏:

  1. 生成的客户端证书不符合OPC UA规范要求
  2. 客户端未信任服务器的证书
  3. 安全参数配置不完整

修正步骤

1. 生成符合OPC UA规范的客户端证书

你的现有证书生成脚本缺少OPC UA强制要求的扩展字段(如密钥用法、主题备用名称),下面是基于cryptography库的修正脚本(该库比pyOpenSSL更易维护且符合现代加密标准):

from cryptography import x509
from cryptography.x509.oid import NameOID, ExtendedKeyUsageOID
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import rsa
from datetime import datetime, timedelta

def generate_opcua_certs():
    # 生成2048位RSA私钥
    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
    )

    # 设置证书主体与颁发者(自签名)
    subject = issuer = x509.Name([
        x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"),
        x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Beijing"),
        x509.NameAttribute(NameOID.LOCALITY_NAME, "Beijing"),
        x509.NameAttribute(NameOID.ORGANIZATION_NAME, "PythonOPCUAClient"),
        x509.NameAttribute(NameOID.COMMON_NAME, "PythonUA_Client"),
    ])

    # 构建符合OPC UA规范的证书
    cert = x509.CertificateBuilder().subject_name(
        subject
    ).issuer_name(
        issuer
    ).public_key(
        private_key.public_key()
    ).serial_number(
        x509.random_serial_number()
    ).not_valid_before(
        datetime.utcnow()
    ).not_valid_after(
        datetime.utcnow() + timedelta(days=365)
    ).add_extension(
        x509.SubjectAlternativeName([x509.DNSName("localhost")]),
        critical=False,
    ).add_extension(
        x509.KeyUsage(
            digital_signature=True,
            key_encipherment=True,
            content_commitment=True,
            data_encipherment=False,
            key_agreement=False,
            key_cert_sign=False,
            crl_sign=False,
            encipher_only=False,
            decipher_only=False
        ),
        critical=True,
    ).add_extension(
        x509.ExtendedKeyUsage([ExtendedKeyUsageOID.CLIENT_AUTH]),
        critical=False,
    ).sign(private_key, hashes.SHA256())

    # 保存私钥与证书
    with open("client_key.pem", "wb") as f:
        f.write(private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.PKCS8,
            encryption_algorithm=serialization.NoEncryption()
        ))

    with open("client_cert.pem", "wb") as f:
        f.write(cert.public_bytes(serialization.Encoding.PEM))

    print("OPC UA合规证书生成完成")

if __name__ == "__main__":
    generate_opcua_certs()

2. 处理服务器DER格式证书

需要将服务器的.der证书转换为PEM格式,供客户端信任:

# 使用openssl命令转换(Windows需安装OpenSSL工具)
openssl x509 -inform der -in server_cert.der -out server_cert.pem

3. 修正客户端连接代码

补充服务器信任证书路径,并调整超时参数适配工业服务器:

from opcua import Client, ua

url = "opc.tcp://srvbeathcs01:44683/ABB/800xA/OPC/UA/Server"
client = Client(url)

# 安全字符串格式:<安全策略>,<安全模式>,<客户端证书>,<客户端私钥>,<信任的服务器证书>
client.set_security_string("Basic256Sha256,Sign,client_cert.pem,client_key.pem,server_cert.pem")
# 针对ABB服务器设置更长超时
client.session_timeout = 30000
client.connect_timeout = 30000

try:
    client.connect()
    print(f"Connected to: {url}")

    servicelevel_node = client.get_node("ns=2;b=ADwDSDdc1EO/1/EufyBvM8qrOcZ9hX9NnGQgzR8uGN1FbmVyZ2llRWxlYy5Db21wdGV1cjkudWludDI=")
    servicelevel_node_value = servicelevel_node.get_value()
    print(servicelevel_node_value)
finally:
    client.disconnect()

4. 服务器端证书信任确认

确保在ABB 800xA的OPC UA服务器配置中,已将生成的client_cert.pem导入信任证书列表,且启用了匿名认证+Sign消息模式。

关键注意事项

  • OPC UA证书必须包含规范要求的扩展字段,否则服务器会直接拒绝连接
  • 客户端必须信任服务器证书,双向验证是Basic256Sha256策略的强制要求
  • ABB 800xA服务器对证书合规性要求严格,需避免使用简化版自签名证书

内容的提问来源于stack exchange,提问作者SinizowN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 02:47:05