SSL 和 aiohttp:禁用 SSL 验证在 python 3.12 上不起作用

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

我有一个来自 aiohttp 的这样的请求:

async with aiohttp.ClientSession(auth=aiohttp.BasicAuth(self.user, self.password), timeout=aiohttp.ClientTimeout(connect=self.timeouts[0], sock_read=self.timeouts[1])) as session:
    async with session.post(self.endpoint, data=query.encode('utf-8'), headers={'content-type' : 'application/xml'}, ssl=False) as response:
        response.raise_for_status()
        return await response.text()

被请求的服务器有一个 SSL 证书,但该证书是“坏的”,不幸的是,这是我们必须使用的软件的问题。所以

ssl=False
用于禁用证书验证。

在 Python 3.7.9 上,此代码运行没有问题,但是当升级到 Python 3.12.3 时,此时开始出现 SSL 验证错误。

Traceback (most recent call last):

  File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\connector.py", line 1116, in _wrap_create_connection
    return await self._loop.create_connection(*args, **kwargs, sock=sock)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "C:\Program Files\Python312\Lib\asyncio\base_events.py", line 1149, in create_connection
    transport, protocol = await self._create_connection_transport(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "C:\Program Files\Python312\Lib\asyncio\base_events.py", line 1182, in _create_connection_transport
    await waiter

  File "C:\Program Files\Python312\Lib\asyncio\sslproto.py", line 578, in _on_handshake_complete
    raise handshake_exc

  File "C:\Program Files\Python312\Lib\asyncio\sslproto.py", line 560, in _do_handshake
    self._sslobj.do_handshake()

  File "C:\Program Files\Python312\Lib\ssl.py", line 917, in do_handshake
    self._sslobj.do_handshake()

ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1000)

The above exception was the direct cause of the following exception:


Traceback (most recent call last):

  File "c:\dev\my_project\server\controllers\rkeeper_cacher\update_task.py", line 38, in rkeeper_cacher_updater
    await _wait_with_raise(tasks)

  File "c:\dev\my_project\server\controllers\rkeeper_cacher\update_task.py", line 17, in _wait_with_raise
    future.result()

  File "c:\dev\my_project\server\controllers\rkeeper_cacher\service.py", line 124, in update_ref_if_need
    if cache_version == -1 or cache_version != await self._get_ref_version(args.rk_ref_name):
                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "c:\dev\my_project\server\controllers\rkeeper_cacher\service.py", line 58, in _get_ref_version
    xml = await self.rk_client.send(
         ^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "c:\dev\my_project\server\ext\rk7_api\async_client\client.py", line 35, in send
    return await self.send_command(command)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "c:\dev\my_project\server\ext\rk7_api\async_client\client.py", line 24, in send_command
    return await self.send_xml(command._serialize())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "c:\dev\my_project\server\ext\rk7_api\async_client\client.py", line 12, in send_xml
    result = await self.query_helper.try_send_str(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "c:\dev\my_project\server\ext\rk7_api\async_client\query_helpers.py", line 24, in try_send_str
    async with session.post(

  File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\client.py", line 1423, in __aenter__
    self._resp: _RetType = await self._coro
                           ^^^^^^^^^^^^^^^^

  File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\client.py", line 701, in _request
    conn = await self._connector.connect(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\connector.py", line 544, in connect
    proto = await self._create_connection(req, traces, timeout)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\connector.py", line 1050, in _create_connection
    _, proto = await self._create_direct_connection(req, traces, timeout)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\connector.py", line 1394, in _create_direct_connection
    raise last_exc

  File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\connector.py", line 1363, in _create_direct_connection
    transp, proto = await self._wrap_create_connection(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "c:\dev\my_project\venv3-12\Lib\site-packages\aiohttp\connector.py", line 1120, in _wrap_create_connection
    raise ClientConnectorSSLError(req.connection_key, exc) from exc

Cannot connect to host 127.0.0.1:3015 ssl:<ssl.SSLContext object at 0x000001E811FEFED0> [[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1000)]: aiohttp.client_exceptions.ClientConnectorSSLError: Cannot connect to host 127.0.0.1:3015 ssl:<ssl.SSLContext object at 0x000001E811FEFED0> [[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1000)]

我认为问题不在于

aiohttp
,而在于Python
ssl
包,但我不知道如何解决这个问题。我尝试过以不同的方式禁用 ssl 验证:

  • 通过
    trust_env=True
    ;
  • ClientSession
    创建我自己的
    ssl_context
    禁用 ssl 检查;
  • 通过禁用 SSL 检查的
    SSLContext
    而不是
    ssl=False
    来执行请求。

我有

Python==3.12.3

aiohappyeyeballs==2.4.4
aiohttp==3.11.10
aiosignal==1.3.1
attrs==24.2.0
frozenlist==1.5.0
idna==3.10
multidict==6.1.0
propcache==0.2.1
yarl==1.18.3
python ssl https aiohttp sslv3
1个回答
0
投票

ssl=False
通过放宽证书验证来降低安全级别,但它并不允许一切。它仍然具有相当合理的默认值。

在这种情况下,您的服务器可能只支持 SSLv3,该协议已被弃用了十年(并且在大多数客户端中禁用的时间更长)。

您需要传递自定义的

SSLContext
以允许低级别的安全性。

你可以尝试这样的事情:

ssl_context = ssl.create_default_context()
ssl_context.minimum_version = ssl.TLSVersion.SSLv3

如果您需要更改密码或文档中的其他任何内容,您可以查看其他选项: https://docs.python.org/3/library/ssl.html#ssl.SSLContext

此外,请务必记住,通过这些设置,您使用的是不安全的连接,应避免发送任何不会通过纯 HTTP 发送的数据。

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