【发布时间】:2012-10-09 07:35:23
【问题描述】:
我有简单的客户端/服务器 SSL 代码,在 Python 3.2 上运行良好。但是,我决定切换到 2.7(由于大量第三方模块),现在代码失败了。代码如下:
客户:
def connect(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect(('localhost', 4430))
self.ssl_sock = ssl.wrap_socket(self.sock, cert_reqs = ssl.CERT_NONE, ssl_version = ssl.PROTOCOL_TLSv1)
服务器:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind((self.hostname, 4430))
self.sock.listen(5)
while True:
self.newsocket, self.fromaddr = self.sock.accept()
self.ssl_sock = ssl.wrap_socket(
self.newsocket,
server_side = True,
certfile = "cert.pem",
ssl_version=ssl.PROTOCOL_TLSv1
)
self._handle_client(self.ssl_sock)
cert.pem(与服务器 .py 文件位于同一目录):
-----BEGIN RSA PRIVATE KEY-----
(812 "random" characters here)
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
(1260 "random" characters here)
-----END CERTIFICATE-----
故障如下:
1. 服务器等待 self.sock.accept()
2.客户端通过self.sock.connect()连接
3. 服务器继续进行 wrap_socket,但失败并出现以下错误:
Traceback (most recent call last):
File "C:\Program Files\Python27\lib\multiprocessing\process.py", line 258, in _bootstrap
self.run()
File "C:\workspace\projectc\server\server\clientlistener.py", line 49, in run
ssl_version=ssl.PROTOCOL_TLSv1
File "C:\Program Files\Python27\lib\ssl.py", line 381, in wrap_socket
ciphers=ciphers)
File "C:\Program Files\Python27\lib\ssl.py", line 141, in __init__
ciphers)
SSLError: [Errno 336265218] _ssl.c:351: error:140B0002:SSL routines:SSL_CTX_use_PrivateKey_file:system lib
附言
1) 我怀疑 wrap_socket 调用,因为即使我对 certfile 使用不存在的文件,也会产生相同的错误。
2)我尝试了对 ssl 上的 python 文档的替代包装(即使用 ssl.SSLContext),当它是 ssl 模块的一部分时,'module' 对象没有属性'SSLContext' 很奇怪。当我使用 Python 3.2 进行尝试时,这不是问题。
更新:
我发现问题只发生在我从 Eclipse 中“运行”时,而不是当我从单独的命令提示符运行这两个文件时。仍在调查此问题...
更新 2: 我用相同的代码尝试了一个非常简单的客户端/服务器脚本,它可以工作。现在,由于服务器代码位于多处理子进程中(由主服务器进程启动),它似乎无法正常工作。相关吗?
【问题讨论】:
-
你应该先包装socket,然后在客户端代码中调用wrapped_socket上的connect方法。
-
我相信任何一种方式都会起作用,因为 wrap 是一个惰性包装(仅在成功连接后包装)。