Python TLS版本匹配

2022-05-29 00:00:00 python ssl tls1.2

问题描述

我使用的是python3.8 我在我的Ubuntu系统上得到以下输出:

>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 1.1.1f  31 Mar 2020'
>>> ssl.PROTOCOL_TLSv1_2
<_SSLMethod.PROTOCOL_TLSv1_2: 5>

我正在尝试通过TLS使用MODBUS TCP连接,因此我在#warning myCode START#warning myCode END行之间添加了一些相关函数

这是客户端:

    class TcpMaster(Master):
        """Subclass of Master. Implements the Modbus TCP MAC layer"""
    
        def __init__(self, host="127.0.0.1", port=502, timeout_in_sec=5.0):
            """Constructor. Set the communication settings"""
            super(TcpMaster, self).__init__(timeout_in_sec)
            self._host = host
            self._port = port
            self._sock = None
    
        def _do_open(self):
            """Connect to the Modbus slave"""
            if self._sock:
                self._sock.close()
            self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.set_timeout(self.get_timeout())
            self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            call_hooks("modbus_tcp.TcpMaster.before_connect", (self, ))
#warning myCode START
            context = SSLContext(PROTOCOL_TLS_CLIENT)
            context.load_verify_locations('cert.pem')
            with create_connection((self._host, self._port)) as client:
                print("1")
                with context.wrap_socket(client, server_hostname=self._host) as tls:
                 print(2)
                 1==1
#warning myCode END
                 
            self._sock.connect((self._host, self._port))
            call_hooks("modbus_tcp.TcpMaster.after_connect", (self, ))
    
    
        def _do_close(self):
            """Close the connection with the Modbus Slave"""
            if self._sock:
                call_hooks("modbus_tcp.TcpMaster.before_close", (self, ))
                self._sock.close()
                call_hooks("modbus_tcp.TcpMaster.after_close", (self, ))
                self._sock = None
                return True
    
        def set_timeout(self, timeout_in_sec):
            """Change the timeout value"""
            super(TcpMaster, self).set_timeout(timeout_in_sec)
            if self._sock:
                self._sock.setblocking(timeout_in_sec > 0)
                if timeout_in_sec:
                    self._sock.settimeout(timeout_in_sec)
    
        def _send(self, request):
            """Send request to the slave"""
            retval = call_hooks("modbus_tcp.TcpMaster.before_send", (self, request))
            if retval is not None:
                request = retval
            try:
                flush_socket(self._sock, 3)
            except Exception as msg:
                #if we can't flush the socket successfully: a disconnection may happened
                #try to reconnect
                LOGGER.error('Error while flushing the socket: {0}'.format(msg))
                self._do_open()
            self._sock.send(request)
    
        def _recv(self, expected_length=-1):
            """
            Receive the response from the slave
            Do not take expected_length into account because the length of the response is
            written in the mbap. Used for RTU only
            """
            response = to_data('')
            length = 255
            while len(response) < length:
                rcv_byte = self._sock.recv(1)
                if rcv_byte:
                    response += rcv_byte
                    if len(response) == 6:
                        to_be_recv_length = struct.unpack(">HHH", response)[2]
                        length = to_be_recv_length + 6
                else:
                    break
            retval = call_hooks("modbus_tcp.TcpMaster.after_recv", (self, response))
            if retval is not None:
                return retval
            return response
    
        def _make_query(self):
            """Returns an instance of a Query subclass implementing the modbus TCP protocol"""
            return TcpQuery()

我不能看到打印程序开始等待并永远持续下去。当我检查Wireshark时,我得到以下输出:

我认为这个错误是由于TLS版本的原因,我的python支持1.2 TLS,但我在Wireshark上看到了TLS1.0版本。我如何解决该问题?

当我中断等待进程时,我收到以下消息:

    with context.wrap_socket(client, server_hostname=self._host) as tls:
  File "/usr/lib/python3.8/ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "/usr/lib/python3.8/ssl.py", line 1040, in _create
    self.do_handshake()
  File "/usr/lib/python3.8/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
KeyboardInterrupt

Process finished with exit code 130 (interrupted by signal 2: SIGINT)

编辑: 如果我试一下下面的线条,它不起作用。客户端发送TLSv1版本。

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.options |= ssl.OP_NO_SSLv3
context.options |= ssl.OP_NO_TLSv1
context.options |= ssl.OP_NO_TLSv1_1

解决方案

我认为出现此错误是因为TLS版本,

这是网络/传输层问题,即客户端没有收到服务器的响应,因此不会发送TCPACK,或者客户端确实发送了ACK,但它在到达服务器的途中丢失了(不清楚您在哪里嗅探流量)。

它与TLS版本无关,因此您无法将其作为此级别进行求解。

相关文章