我正在尝试连接到 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
你能帮我吗?
您的证书需要主题备用名称 (SAN),其中包含应用程序 uri 作为 urn 字段作为第一个参数,然后是您的客户端 ip 或主机名。
如果您切换到 asyncua 而不是不再维护的 opcua 库,有一些方法可以创建证书。请参阅:https://github.com/FreeOpcUa/opcua-asyncio/blob/master/examples/client-with-encryption.py