Python pyOpenssl服务器无法协商TLS 1.3

3

我在使用pyOpenssl服务器协商TLS 1.3时遇到了困难。我尝试使用支持1.3的openssl s_client连接服务器,但没有成功。然而,该服务器可以使用TLS 1.2及以下版本。请问我错过了什么?谢谢!

tls_server.py
-------------

import socket
from OpenSSL import SSL
sslctx = SSL.Context(SSL.TLSv1_2_METHOD)
sslctx.set_options(SSL.OP_NO_TLSv1_2 | SSL.OP_NO_TLSv1_1 | SSL.OP_NO_TLSv1)
sslctx.set_cipher_list(b"TLS_AES_128_GCM_SHA256:AES128-GCM-SHA256")
sslctx.use_privatekey_file("key.pem")
sslctx.use_certificate_file("cert.pem")

bindsocket = socket.socket()
bindsocket.bind(('', 4433))
bindsocket.listen(5)

while True:
    newsocket, fromaddr = bindsocket.accept()
    sslconn = SSL.Connection(sslctx, newsocket)
    sslconn.set_accept_state()
    sslconn.do_handshake()
    print(f"List of ciphers: {sslconn.get_cipher_list()}")
    req = sslconn.read(4096)
    print(req)
    sslconn.write(b"HTTP/1.1 200 OK\r\nServer: my-special\r\nContent-length: 10\r\n\r\nHello!\r\n\r\n")
    sslconn.set_shutdown(SSL.SENT_SHUTDOWN)


当我强制客户端仅连接tls1.3时,出现以下错误。
$ openssl version
OpenSSL 1.1.1d  10 Sep 2019
$ openssl s_client -connect localhost:4433 -tls1_3
4641068480:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:ssl/record/rec_layer_s3.c:1544:SSL alert number 40

服务器返回跟踪信息:


$ python3.8 tls_server.py
Traceback (most recent call last):
  File "tls_server.py", line 18, in <module>
    sobj.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/OpenSSL/SSL.py", line 1934, in do_handshake
    self._raise_ssl_error(self._ssl, result)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/OpenSSL/SSL.py", line 1671, in _raise_ssl_error
    _raise_current_error()
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/OpenSSL/_util.py", line 54, in exception_from_error_queue
    raise exception_type(errors)
OpenSSL.SSL.Error: [('SSL routines', 'tls_post_process_client_hello', 'no shared cipher')]
$

当TLS 1.2连接成功后,我看到服务器返回了以下密码套件,证实支持TLS 1.3。

$ python3.8 tls_server.py
List of ciphers: ['TLS_AES_256_GCM_SHA384', 'TLS_CHACHA20_POLY1305_SHA256', 'TLS_AES_128_GCM_SHA256', 'AES128-GCM-SHA256']
b'GET /\n'

我使用的工具版本。

$ python3.8 -m OpenSSL.debug
pyOpenSSL: 19.1.0
cryptography: 2.9.2
cffi: 1.13.2
cryptography's compiled against OpenSSL: OpenSSL 1.1.1g  21 Apr 2020
cryptography's linked OpenSSL: OpenSSL 1.1.1g  21 Apr 2020
Pythons's OpenSSL: OpenSSL 1.1.1d  10 Sep 2019
Python executable: /Library/Frameworks/Python.framework/Versions/3.8/bin/python3.8
Python version: 3.8.1 (v3.8.1:1b293b6006, Dec 18 2019, 14:08:53)
[Clang 6.0 (clang-600.0.57)]
Platform: darwin
1个回答

3

我对这个配置不确定:

sslctx = SSL.Context(SSL.TLSv1_2_METHOD)
sslctx.set_options(SSL.OP_NO_TLSv1_2 | SSL.OP_NO_TLSv1_1 | SSL.OP_NO_TLSv1)
你是不是在说只使用TLSv1.2,然后也不要使用TLSv1-TLSv1.2?现在没有“SSL.TLSv1_3_METHOD”选项,你应该使用“SSL.TLS_METHOD”, 但看起来PyOpenSSL还没有暴露它。似乎有一个(目前)开放的问题关于如何更好地配置它,但仍然没有添加“SSL.TLS_METHOD”。

感谢您的回复。由于没有可用的SSL.TLSv1_3_METHOD,我只能使用更高版本的协议,即SSL.TLSv1_2_METHODsslctx = SSL.Context(SSL.TLSv1_2_METHOD)。在配置文件的下一行中,我尝试了许多选项,以查看是否可以强制仅监听TLS 1.3,但没有成功。也尝试了不使用此选项,结果相同。 sslctx.set_options(SSL.OP_NO_TLSv1_2 | SSL.OP_NO_TLSv1_1 | SSL.OP_NO_TLSv1)。感谢您指出这个未解决的问题。有办法让TLS 1.3与pyopenssl进行协商吗? - Pr1614
嗯...看起来好像不行。你应该使用sslctx = SSL.Context(SSL.TLS_METHOD)来设置,但似乎pyopenssl没有暴露这个功能。 - Barry Pollard
似乎SSL.Context(SSL.SSLv23_METHOD)能够进行TLS 1.3版本的握手协商,至少在作为客户端使用时是如此(Python 2.7,Debian Python OpenSSL包19.0.0-1,Debian openssl 1.1.1d)。 - Patrick Mevzek
@PatrickMevzek,你有一个代码示例吗?我尝试过了,但没有成功。 - Santiago Rodriguez
@SantiagoRodriguez 如果您有具体问题,请开一个新的帖子,附上您的代码,解释您想要做什么以及哪些部分出了问题。 - Patrick Mevzek
我刚刚看到这个,目前 SSL.TLS_METHOD 看起来是可以使用的(链接:https://github.com/pyca/pyopenssl/blob/main/src/OpenSSL/SSL.py#L140)。而且对于非TLS1.3连接,`SSL.Context(method=SSL.TLS_METHOD)` 的工作正常。然而,在TLS1.3上,我遇到了 OpenSSL.SSL.Error: [('SSL routines', '', 'wrong version number')] 的错误。 - Nexus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接