使用Python连接到OPC Ua Basic256Sha256安全策略

问题描述 投票:0回答:1

我正在尝试连接到 OPC Ua 服务器,以便能够使用 python 代码读取变量。

服务器和客户端位于 Windows Server 2022 上

该服务器的安全策略:Basic256Sha256,消息安全模式:签名和匿名认证。

我设法与 Ua Expert 连接并获取变量值

我已经测试了几个Python库,但我无法得到一个可以工作的脚本。我认为这是因为证书的原因,但我不太了解证书的所有内容。

在下面的例子中:

from opcua import Client, ua

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


client.set_security_string("Basic256Sha256,Sign,cert.pem,key.pem")

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)

client.disconnect()

如何获取cert.pem和key.pem,有一个简单的python脚本来生成它们吗?我在 .der 中也有一个服务器证书,我需要用它做些什么吗?

我尝试使用此脚本生成证书:

from OpenSSL import crypto

def generate_certificates():
    # Générer une clé privée
    key = crypto.PKey()
    key.generate_key(crypto.TYPE_RSA, 2048)

    # Générer un certificat auto-signé
    cert = crypto.X509()
    cert.set_version(2)
    cert.set_serial_number(1000)
    cert.get_subject().CN = "test.com"
    cert.set_issuer(cert.get_subject())
    cert.set_notBefore(b'20240101000000Z')
    cert.set_notAfter(b'20250101000000Z')
    cert.set_pubkey(key)
    cert.sign(key, 'sha256')

    # Sauvegarder la clé privée et le certificat dans des fichiers
    with open("key.pem", "wb") as key_file:
        key_file.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key))

    with open("cert.pem", "wb") as cert_file:
        cert_file.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))

    print("Certificats generated!")

if __name__ == "__main__":
    generate_certificates()

证书已生成在此输入图片描述

在服务器端,我收到请求,并且我可以信任此示例中的证书(test.com)。

但是我在尝试连接时遇到错误:

Received an error: MessageAbort(error:StatusCode(BadSecurityChecksFailed), reason:Could not verify security on OpenSecureChannel request.)
Received an error: MessageAbort(error:StatusCode(BadSecurityChecksFailed), reason:Could not verify security on OpenSecureChannel request.)
Protocol Error
Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages\opcua\client\ua_client.py", line 101, in _run
    self._receive()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages\opcua\client\ua_client.py", line 121, in _receive
    self._call_callback(0, ua.UaStatusCodeError(msg.Error.value))
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages\opcua\client\ua_client.py", line 129, in _call_callback
    raise ua.UaError(
opcua.ua.uaerrors._base.UaError: No future object found for request: 0, callbacks in list are dict_keys([1])
exception calling callback for <Future at 0x1a6fcaad5b0 state=cancelled>
Traceback (most recent call last):
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\concurrent\futures\_base.py", line 340, in _invoke_callbacks
    callback(self)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages\opcua\client\ua_client.py", line 201, in clb
    response = struct_from_binary(ua.OpenSecureChannelResponse, future.result())
                                                                ^^^^^^^^^^^^^^^
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\concurrent\futures\_base.py", line 447, in result
    raise CancelledError()
concurrent.futures._base.CancelledError
Traceback (most recent call last):
  File "C:\Users\Administrator\Desktop\Python\Code.py", line 9, in <module>
    client.connect()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages\opcua\client\client.py", line 275, in connect
    self.open_secure_channel()
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages\opcua\client\client.py", line 335, in open_secure_channel
    result = self.uaclient.open_secure_channel(params)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages\opcua\client\ua_client.py", line 275, in open_secure_channel
    return self._uasocket.open_secure_channel(params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\site-packages\opcua\client\ua_client.py", line 209, in open_secure_channel
    response = clb.future.result(self.timeout)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Lib\concurrent\futures\_base.py", line 458, in result
    raise TimeoutError()
TimeoutError

你能帮我吗?

python windows certificate sha256 opc-ua
1个回答
0
投票

您的证书需要主题备用名称 (SAN),其中包含应用程序 uri 作为 urn 字段作为第一个参数,然后是您的客户端 ip 或主机名。

如果您切换到 asyncua 而不是不再维护的 opcua 库,有一些方法可以创建证书。请参阅:https://github.com/FreeOpcUa/opcua-asyncio/blob/master/examples/client-with-encryption.py

© www.soinside.com 2019 - 2024. All rights reserved.