ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh 密钥太小 (_ssl.c:1108)

daz*_*sed 6 python ssl

我遇到了 ssl 错误!?

从 19.10 升级到 20.04 并收到此错误:

ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:1108)
Run Code Online (Sandbox Code Playgroud)

它是由 python 脚本调用 oanda.com 的 rest API 引发的。

使用 Postman 或 OANDA 的 java 应用程序连接到服务都可以正常工作。另外,让 Python 脚本在 RPi 上运行正常,经过一次更改后,请参见下文!

20.04 - OpenSSL 1.1.1f 2020 年 3 月 31 日

RPi - OpenSSL 1.1.1d 2019 年 9 月 10 日

问题是还对RPI和研究发现一对夫妇的建议,将设置更改CipherString = DEFAULT@SECLEVEL=2CipherString = DEFAULT@SECLEVEL=1了在/etc/ssl/openssl.cnf文件中。这适用于 RPi,但不适用于 Ubuntu 20.04。

关于如何解决这个问题的任何想法?


错误报告:

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 352, 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.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()
ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:1108)
Run Code Online (Sandbox Code Playgroud)

moo*_*moo 1

从 18.04 LTS 升级到 20.04 LTS 后,我在尝试连接到 Exchange 服务器时遇到了此错误。原因是默认的上游 Debian OpenSSL 设置变得更加安全。在 OpenSSL 中,CipherString现在设置为DEFAULT@SECLEVEL=2

此更改的背景/理由详细信息如下: https: //weakdh.org/

理想情况下,应该提高服务器的安全性,而不是在客户端上实施此解决方法。然而,在许多情况下,这是不可能的。

我可以通过创建SSLContext来调整用于连接的密码来解决这个问题。以下是代码示例(用于 SMTPS 连接 - 发送电子邮件):

connection = smtplib.SMTP(
    config['Email']['host'] + ':' + config['Email']['port'])
context=ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
# Either of the following context settings worked for me - choose one
# context.set_ciphers('HIGH:!DH:!aNULL')
context.set_ciphers('DEFAULT@SECLEVEL=1')
connection.starttls(context=context)
connection.login(config['Email']['user'], config['Email']['pw'])
connection.sendmail(config['Email']['sender'], recipients, msg.as_string())
connection.close()
Run Code Online (Sandbox Code Playgroud)

重要的几行是这些 - 选择以下调整之一CipherString

context.set_ciphers('HIGH:!DH:!aNULL')
context.set_ciphers('DEFAULT@SECLEVEL=1')
Run Code Online (Sandbox Code Playgroud)

但如果可能的话,更喜欢修复服务器!

要针对 urllib3 调整上述内容,请参阅以下答案:

如何在通过python请求模块发送请求时选择特定的密码


小智 1

在按照本文所述降低 SSL 安全级别后,我的项目得以正常运行。

Ubuntu 20.04 - 如何设置较低的 SSL 安全级别?