- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
根据 Python 3 documentation :
SSLSocket.shared_ciphers()
Return the list of ciphers shared by the client during the handshake.
我将其解释为 TLS CLIENT_HELLO 数据包中的“密码套件” block (握手的第一个数据包)将被返回。给定以下 openssl 命令:
openssl s_client -connect 172.16.30.3:443 -cipher ECDHE-RSA-AES128-SHA
电线上的数据包,如 wireshark 中所示,显示为带有该单一密码(和 RENEGOTIATION 伪密码):
但是,当我的服务器代码在握手后调用 shared_ciphers() 时,返回的是服务器的整个密码套件,而不是客户端在握手中发送的密码。这是服务器打印的内容:
# ./shared_ciphers_test.py
Server Cipher Suite from get_ciphers():
ECDHE-ECDSA-AES128-SHA256
ECDHE-RSA-AES128-SHA
ECDHE-ECDSA-AES128-SHA
ECDHE-RSA-RC4-SHA
Listening...
Connection accepted from ('172.16.30.4', 32888)
Client Cipher Suite from shared_ciphers():
ECDHE-ECDSA-AES128-SHA256
ECDHE-RSA-AES128-SHA
ECDHE-ECDSA-AES128-SHA
ECDHE-RSA-RC4-SHA
#
问题:
这是服务器代码:
#!/usr/bin/python3
import socket, ssl, sys, time
listener = socket.socket()
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listener.bind(('0.0.0.0', 443))
listener.listen(5)
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile='certchain.pem', keyfile='keyfile.pem')
context.set_ciphers('ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-RC4-SHA')
print('Server Cipher Suite from get_ciphers():')
for item in context.get_ciphers():
print(' {}'.format(item['name']))
print('Listening...')
newsocket, fromaddr = listener.accept()
connstream = context.wrap_socket(newsocket, server_side=True)
print('Connection accepted from {}'.format(connstream.getpeername()))
print('Client Cipher Suite from shared_ciphers():')
for item in connstream.shared_ciphers():
print(' {}'.format(item[0]))
sys.exit(0)
最佳答案
这是一个错误。
查看the C implementation for the ssl module可以看出两者都是get_ciphers和 shared_ciphers通过使用 SSL_get_ciphers 实现,尽管一个使用上下文作为基础,另一个使用来自当前连接的 SSL 对象。 SSL_get_ciphers
从 SSL 或上下文对象访问 cipher_list
属性,这似乎是最初配置的密码列表。
我认为获取共享密码的正确函数实际上是
SSL_get_client_ciphers .此函数访问
ssl->session->ciphers
,与更明确命名(但未记录)的
SSL_get_shared_ciphers
函数相同。
SSL_get_client_ciphers
仅在 OpenSSL 1.1.0 之后可用,因此需要直接访问旧版本的
ssl->session->ciphers
。
看起来 OpenSSL 根本不提供这样的功能,因此 Python 也不能真正提供这个功能。功能SSL_get_client_ciphers , SSL_get_shared_ciphers
和对 ssl->session->ciphers
的访问都提供对客户端提供的密码的访问,即 SSL_get_client_ciphers
的名称建议与 SSL_get_shared_ciphers
建议相反。此信息与内部 ssl3_choose_cipher
函数中的服务器端 cipher_list
相结合,其中选择了通用密码。获取实际共享的密码(另外受使用证书类型的限制)将意味着重新实现此功能的主要部分。
有趣的是,看起来 OpenSSL 开发人员甚至不知道 ssl->session->ciphers
真正包含什么。从 0.9.8 天到最新版本的 OpenSSL,可以找到 ssl_session_st
结构的 ciphers
成员的以下文档:
STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */
基于此,他们似乎(错误地)认为此结构包含共享密码,但他们不确定。
请注意,我已经为 Python 提交了一个关于这个错误实现的功能的错误:https://bugs.python.org/issue32813 .根据 OpenSSL 提供的内容,我的猜测是该函数应该从 Python 中完全删除,而不是返回错误的数据。我还为 OpenSSL 提交了一个关于 SSL_get_shared_ciphers 的误导性名称的错误:https://github.com/openssl/openssl/issues/5317 .
关于Python 'ssl' shared_ciphers() 没有记录在案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48717497/
我是一名优秀的程序员,十分优秀!