【问题标题】:Python request SSLError bad handshakesPython请求SSLError错误握手
【发布时间】:2021-02-28 15:33:40
【问题描述】:

我已经成功向 Postman 上的一个站点发出请求,但是当我复制 Python 代码并执行它时,它给了我以下错误

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 665, in urlopen
    httplib_response = self._make_request(
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 376, in _make_request
    self._validate_conn(conn)
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 996, in _validate_conn
    conn.connect()
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 366, in connect
    self.sock = ssl_wrap_socket(
  File "/usr/lib/python3/dist-packages/urllib3/util/ssl_.py", line 370, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/usr/lib/python3/dist-packages/urllib3/contrib/pyopenssl.py", line 491, in wrap_socket
    raise ssl.SSLError("bad handshake: %r" % e)
ssl.SSLError: ("bad handshake: SysCallError(-1, 'Unexpected EOF')",)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 719, in urlopen
    retries = retries.increment(
  File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 436, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='...', port=443): Max retries exceeded with url: /dkmh/login.asp (Caused by SSLError(SSLError("bad handshake: SysCallError(-1, 'Unexpected EOF')")))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 23, in <module>
    response = requests.request("POST", url, headers=headers, data = payload, verify=False)
  File "/usr/lib/python3/dist-packages/requests/api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 514, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='...', port=443): Max retries exceeded with url: /dkmh/login.asp (Caused by SSLError(SSLError("bad handshake: SysCallError(-1, 'Unexpected EOF')")))

这是完整的代码(我已经删除了原来的网址)

import requests

url = "https://xxx/login.asp"

payload = 'chkSubmit=ok&txtLoginId=19020055&txtPassword=qj28r8&txtSel=1'
headers = {
  'Connection': 'keep-alive',
  'Cache-Control': 'max-age=0',
  'Upgrade-Insecure-Requests': '1',
  'Origin': 'https://xxx',
  'Content-Type': 'application/x-www-form-urlencoded',
  'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36',
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
  'Sec-Fetch-Site': 'same-origin',
  'Sec-Fetch-Mode': 'navigate',
  'Sec-Fetch-User': '?1',
  'Sec-Fetch-Dest': 'document',
  'Referer': 'https://xxx/login.asp',
  'Accept-Language': 'vi-VN,vi;q=0.9,en-US;q=0.8,en;q=0.7',
  'Cookie': '_ga=GA1.3.1781562536.1609987797; ASPSESSIONIDAQDQQQSC=MDJHCACBKMNBFFLOGABMCGEA; UnivId=; intUserLogedin=92573; selab=intUserRef=92573; first=PortalModule%5F376; intUserLogedin=92573; selab=intUserRef=92573; UnivId=; first=PortalModule%5F376'
}

response = requests.request("POST", url, headers=headers, data = payload, verify=False)

print(response.text.encode('utf8'))

根据我的检查,该站点的 TLS 版本是 1.0。我用 python 3.6、3.7、3.8 尝试了脚本,尝试安装 requests[security],但以上操作均无效!

SSLLabs 的输出:https://www.ssllabs.com/ssltest/analyze.html?d=daotao.vnu.edu.vn

【问题讨论】:

  • 这可以是任何东西。服务器需要像 RC4 或 3DES 这样的弱密码,需要客户端证书,与现代 TLS 堆栈不兼容,...... - 根据这些信息无法判断。如果服务器是公开的,那么提供 URL 或 SSLLabs 的完整输出会有所帮助。如果您可以控制服务器,请查看服务器端日志文件以获取可能出现的问题的提示。
  • 我在问题末尾添加了 SSLLabs 分析的链接。该网站是我大学的网站

标签: python ssl python-requests postman


【解决方案1】:

我的天啊,服务器完全不安全,而且崩溃得无可救药:

唯一受支持且较弱且尚未不安全的密码是 3DES-CBC:

但是,由于此密码很弱,因此 OpenSSL 的常见构建不支持它 - 这是 Python 中 SSL 的基础。 Is 可用于旧版本的 Python 或 OpenSSL 的特殊版本,但如果显式启用。

请参阅 How to work with Python requests with hosts only supporting TLS 1.0Requests failing to connect to a TLS server,了解如何从 Python 启用此密码 - 只要它已构建到底层 OpenSSL 库中即可。

【讨论】:

  • 谢谢。在遵循您给出的线程之后,它给了我“由 SSLError(SSLError('No cipher can be selected.',),) 引起)。我正在使用 Ubuntu 20.04 LTS。此外,您能否指定一个支持 3DES-CBC 密码的 python 版本,或者我可以咨询以创建“OpenSSL 的特殊构建”的链接?
  • @HoàngTùng:没有特定的 Python 版本,这是 OpenSSL 构建选项的问题,然后用这个特定的 OpenSSL 构建编译 Python。详细信息取决于您的操作系统。例如,我有一个旧版本的 Anaconda Python 3.6.3,它带有 OpenSSL 1.0.2,并且仍然支持 3DES。
  • 我遵循以下 [superuser.com/questions/1179309/… 在自定义 OpenSSL 构建上启用 3DES SSL 密码。但是,仍然显示相同的消息“无法选择密码”
  • @HoàngTùng:您不仅需要启用 3DES 的 OpenSSL,而且还需要针对它编译 Python 才能使用 - 请参阅 here 了解有关如何执行此操作的各种说明。跨度>
猜你喜欢
  • 1970-01-01
  • 2018-11-01
  • 2018-08-16
  • 1970-01-01
  • 2019-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多