You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无证书情况下能否在客户端与服务器间建立SSL Socket?

无证书SSL Socket能否实现?

我们需要在客户端与服务器之间建立仅加密通信、无需身份验证的SSL连接,目的是防止(至少阻碍)通信被窃听。限制条件包括:

  • 客户端/服务器进程生命周期较短,运行在多台机器上,可能未连接互联网
  • 所有机器使用相同的文件/代码,因此“私钥”会成为公知信息,失去私有属性

现有代码

server.py

import socket
import ssl

address = ('localhost', 12345)

context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.verify_mode = ssl.CERT_NONE

with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as unsecured_socket:
    unsecured_socket.bind(address)
    unsecured_socket.listen(5)
    with context.wrap_socket(unsecured_socket, server_side=True) as sock:
        conn, addr = sock.accept()
        print(f"Accepted: {addr}")

client.py

import socket
import ssl

address = ('localhost', 12345)

context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE

with socket.create_connection(address) as unsecured_socket:
    with context.wrap_socket(unsecured_socket) as sock:
        print(sock.version())

运行报错

服务器端错误

Traceback (most recent call last):
  File "C:/experiments/server.py", line 13, in <module>
    conn, addr = sock.accept()
  File "C:\Program Files\Python313\Lib\ssl.py", line 1418, in accept
    newsock = self.context.wrap_socket(newsock,
  File "C:\Program Files\Python313\Lib\ssl.py", line 455, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Program Files\Python313\Lib\ssl.py", line 1076, in _create
    self.do_handshake()
  File "C:\Program Files\Python313\Lib\ssl.py", line 1372, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: NO_SHARED_CIPHER] no shared cipher (_ssl.c:1028)

客户端错误

Traceback (most recent call last):
  File "C:\experiments\client.py", line 11, in <module>
    with context.wrap_socket(unsecured_socket) as sock:
  File "C:\Program Files\Python313\Lib\ssl.py", line 455, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Program Files\Python313\Lib\ssl.py", line 1076, in _create
    self.do_handshake()
  File "C:\Program Files\Python313\Lib\ssl.py", line 1372, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1028)

问题原因及解决方案

报错核心原因是:默认TLS配置中,服务器需要证书完成密钥交换,我们未提供证书,导致无可用共享加密套件。要实现无证书加密,需使用**匿名Diffie-Hellman(ADH)**系列加密套件,这类套件无需证书即可完成密钥协商。

修改后的代码如下:

修正后的server.py

import socket
import ssl

address = ('localhost', 12345)

context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.verify_mode = ssl.CERT_NONE
# 添加匿名加密套件
context.set_ciphers('ADH-AES256-GCM-SHA384:ADH-AES128-GCM-SHA256')

with socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) as unsecured_socket:
    unsecured_socket.bind(address)
    unsecured_socket.listen(5)
    with context.wrap_socket(unsecured_socket, server_side=True) as sock:
        conn, addr = sock.accept()
        print(f"Accepted: {addr}")
        # 测试发送数据
        conn.sendall(b"Hello from server")
        data = conn.recv(1024)
        print(f"Received: {data.decode()}")

修正后的client.py

import socket
import ssl

address = ('localhost', 12345)

context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
# 添加和服务器一致的匿名加密套件
context.set_ciphers('ADH-AES256-GCM-SHA384:ADH-AES128-GCM-SHA256')

with socket.create_connection(address) as unsecured_socket:
    with context.wrap_socket(unsecured_socket) as sock:
        print(f"TLS版本: {sock.version()}")
        # 测试接收和发送数据
        data = sock.recv(1024)
        print(f"Received: {data.decode()}")
        sock.sendall(b"Hello from client")

注意事项

  • 匿名加密套件安全性低于带证书的套件,无法验证通信方身份,存在中间人攻击风险,但能满足“仅加密防窃听”的需求
  • 客户端和服务器必须使用一致的加密套件列表,否则仍会出现无共享套件的错误
  • 不同Python或OpenSSL版本支持的匿名套件可能不同,可通过openssl ciphers -v | grep ADH命令查看当前环境支持的ADH套件

内容的提问来源于stack exchange,提问作者AJNeufeld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 06:08:17