在 Python 中使用 Diffie-Hellman 的服务器端 SSL

Server Side SSL using Diffie-Hellman in Python

我正在尝试使用 Diffie-Hellman SSL 设置套接字,但似乎找不到有关如何执行此操作的任何文档。我注意到 Python 3.3+ 中的 SSLContext 支持 load_dh_params 和 set_ecdh_curve,这表明可以使用 DH。

我对使用 SSL 还很陌生,所以可能遗漏了一些明显的东西,但这是我正在使用的代码:

sock = socket.socket()
sock.bind((HOST, PORT))
sock.listen()
context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS)
context.set_ecdh_curve('prime256v1')
ssock, address = self._server.accept()
ssock= context.wrap_socket(ssock, server_side=True)

使用这段代码时,出现错误:

ssl.SSLError: [SSL: NO_SHARED_CIPHER] 无共享密码

我试过如下设置密码:

context.set_ciphers('ECDHE-RSA-AES256-GCM-SHA384')

但我尝试过的所有密码仍然会抛出相同的异常。

如果有人能指出我出错的地方或提供使用 DH SSL 的工作示例,将不胜感激!

TLS 密码定义了密钥交换、身份验证方法、对称加密算法和 HMAC。您明确尝试使用的密码中的身份验证方法是 RSA,即使用带有 RSA public 密钥的证书。如果您改为使用默认密码集,则身份验证方法为 RSA 或 ECDSA。

这两种身份验证方法都需要服务器端的适当证书,即使用 RSA 或 ECC public 密钥。由于您尚未配置任何证书,因此无法使用这些密码。这实质上意味着客户端提供的密码(通常还需要基于证书的身份验证)none 可用于连接,因此 NO_SHARED_CIPHER.

您需要做的事情:

  • 推荐的方式是在客户端信任的服务器上设置证书。参见 SSLContext.load_cert_chain
  • 或者您可以使用不需要身份验证的密码,例如 ADH-AES256-GCM-SHA384。请注意,您还需要在客户端中显式配置密码,因为出于安全原因,默认情况下 TLS 堆栈不使用未经身份验证的密码,因为这种方式不会检测到中间人攻击。