如何使用 Python 创建和连接匿名 DH TLS 套接字并通过它们安全地进行身份验证而不可能进行凭证转发?

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

我正在编写一个点对点协议,其中节点可以相互连接,并且应该使用 TLS 以及与 Diffie-Hellman 交换一致的会话密钥对连接进行加密。然而,使用任何类型的证书都会很乏味,因为建立 TLS 连接后,每对节点仍然必须使用 ECDSA 质询响应协议(这使用 OpenSSL 不支持的密码套件)进行相互身份验证。

  1. 鉴于我可以控制客户端和服务器上的

    ssl
    ,如何使用Python标准库
    SSLContext
    模块来建立这样一个不需要设置蛇油证书的TLS连接?

  2. 如何在 TLS 握手完成后使用质询响应协议进行身份验证,从而排除 Mallory 使用凭证转发的可能性?

python-3.x authentication ssl diffie-hellman
1个回答
0
投票

对于第 1 部分,一种可能性是使用带有

AECDH
的 OpenSSL 密码套件,例如
AECDH-AES256-SHA
。对于服务器,代码是

context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.set_ciphers("AECDH-AES256-SHA:@SECLEVEL=0")

with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as sock:
    sock.bind(('127.0.0.1', 8443))
    sock.listen(5)
    with context.wrap_socket(sock, server_side=True) as ssock:
        conn, addr = ssock.accept()

对于客户端代码,您可以使用以下内容

context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.set_ciphers("AECDH-AES256-SHA:@SECLEVEL=0")
context.check_hostname = False

with socket.create_connection(('localhost', 8443)) as sock:
    with context.wrap_socket(sock) as conn:
        ...

值得注意的是,需要指定

:@SECLEVEL=0
才能正常工作。

对于第2部分和挑战响应协议,可以使用通道绑定函数——

的返回值
conn.get_channel_binding(cb_type='tls-unique')

作为挑战-响应协议中签名消息的一部分。这是一个 96 位值。

然而,该解决方案的安全性还远未达到完美。值得注意的是,使用

AECDH
密码似乎限制了与 TLS 1.2 的连接,并且针对 get_channel_binding(cb_type='tls-unique') 存在
攻击
,基本上使值的长度减半,即有效的安全性仅为 48 位。

在 TLS 1.3 中,可以选择导出更长的值,即类型为

get_channel_binding
tls-exporter
,但是 Python 3 SSL 模块目前不支持。另一方面,对于 TLS 1.3,这些匿名 Diffie-Hellman 密码套件似乎不再可能。

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