3

我有简单的客户端/服务器 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. server 在 self.sock.accept() 上等待
2. client 用 self.sock.connect() 连接
3. server 继续 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

PS
1)我怀疑 wrap_socket 调用,因为即使我使用不存在的文件作为 certfile,也会产生相同的错误。
2)我在ssl上的python文档上尝试了替代包装(即使用ssl.SSLContext),奇怪的是'module'对象没有属性'SSLContext',当它是ssl模块的一部分时。当我使用 Python 3.2 进行尝试时,这不是问题。

更新:
我发现问题只发生在我从 Eclipse 中“运行”时,而不是当我从单独的命令提示符运行这两个文件时。还在调查这个问题...

更新 2: 我尝试了一个非常简单的客户端/服务器脚本,代码相同,它可以工作。现在,由于服务器代码位于多处理子进程中(由主服务器进程启动),它似乎无法正常工作。有关的?

4

2 回答 2

3

问题解决了。我相信 Eclipse 持有一些残余信息,尽管我从未弄清楚它持有什么信息。它可能与从 python 3.2 到 2.7 的迁移有关,尽管我之前已经在运行配置中更改了它。重置 Eclipse 环境有效(仅仅重启计算机是不够的)。

于 2012-10-09T09:21:42.573 回答
2

我的解决方案是,在创建我的 .pem 文件时,我设置了一个空白密码并假设它没有密码。所以服务器仍然希望使用密码。我不得不手动删除密码。

如果对任何人有帮助,这里有一些指导方法(另外,请注意我正在为 iOS 应用程序的服务器端编写 Python 代码)

注意:需要先按照苹果开发者网站的指示创建证书,然后导出 .p12 文件,通过导出创建的嵌入式私钥(在“钥匙串访问”中),而不是实际的证书 ———————— —————————————————————————————————————————————————————— ——————————————— FOR DEVELOPMENT CERT:得到p12文件后,需要在终端执行以下命令,将其转换为PEM格式: $ openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns_dev.p12 $ openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns_dev.p12

如果您希望删除密码,请执行以下操作:(注意:在导出/转换时使用“空白”密码,实际上仍然是在设置密码,因此如果您打算没有密码,您仍应执行以下操作)$ openssl rsa -in apns-dev-key.pem -out apns-dev-key-noenc.pem

最后,您需要将密钥和证书文件组合成一个 apns-dev.pem 文件,我们将在连接到 APNS 时使用:

$ cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem

———————————————————————————————————— FOR PRODUCTION CERT:得到p12文件后,需要通过从终端执行以下命令转换为 PEM 格式: $ openssl pkcs12 -clcerts -nokeys -out apns-prod-cert.pem -in apns_prod.p12 $ openssl pkcs12 -nocerts -out apns-prod-key.pem -in apns_prod.p12

如果您希望删除密码,请执行以下操作:(注意:在导出/转换时使用“空白”密码,实际上仍然是在设置密码,因此如果您打算没有密码,您仍应执行以下操作)$ openssl rsa -in apns-prod-key.pem -out apns-prod-key-noenc.pem

最后,您需要将密钥和证书文件组合成一个 apns-dev.pem 文件,我们将在连接到 APNS 时使用:

$ cat apns-prod-cert.pem apns-prod-key-noenc.pem > apns-prod.pem

于 2014-10-02T01:07:26.670 回答