我正在尝试使用httplib的HTTPSConnection进行客户端验证,使用PKCS#12证书。我知道证书很好,因为我可以在MSIE和Firefox中使用它连接到服务器。
这是我的连接功能(证书包含私钥)。我已经把它简化为基础:
def connect(self, cert_file, host, usrname, passwd):
self.cert_file = cert_file
self.host = host
self.conn = httplib.HTTPSConnection(host=self.host, port=self.port, key_file=cert_file, cert_file=cert_file)
self.conn.putrequest('GET', 'pathnet/,DanaInfo=200.222.1.1+')
self.conn.endheaders()
retCreateCon = self.conn.getresponse()
if is_verbose:
print "Create HTTPS connection, " + retCreateCon.read()
(注意:请不要对硬编码路径发表评论 - 我试图让它首先工作;之后我会做得很好。硬编码路径是正确的,因为我连接到它MSIE和Firefox。我更改了帖子的IP地址。)
当我尝试使用PKCS#12证书(.pfx文件)运行时,我会回到看似openSSL错误的内容。这是整个错误追溯:
File "Usinghttplib_Test.py", line 175, in t.connect(cert_file=opts["-keys"], host=host_name, usrname=opts["-username"], passwd=opts["-password"]) File "Usinghttplib_Test.py", line 40, in connect self.conn.endheaders() File "c:\python26\lib\httplib.py", line 904, in endheaders self._send_output() File "c:\python26\lib\httplib.py", line 776, in _send_output self.send(msg) File "c:\python26\lib\httplib.py", line 735, in send self.connect() File "c:\python26\lib\httplib.py", line 1112, in connect self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file) File "c:\python26\lib\ssl.py", line 350, in wrap_socket suppress_ragged_eofs=suppress_ragged_eofs) File "c:\python26\lib\ssl.py", line 113, in __init__ cert_reqs, ssl_version, ca_certs) ssl.SSLError: [Errno 336265225] _ssl.c:337: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib
注意,openSSL错误(列表中的最后一个条目)注意到“PEM lib”,我发现它很奇怪,因为我不想使用PEM证书。
对于踢,我将PKCS#12证书转换为PEM证书,并使用 运行相同的代码。在那种情况下,我没有收到任何错误,我被提示输入PEM密码短语,代码确实试图到达服务器。 (我收到了回复“服务不是 可用。请稍后再试。“,但我相信这是因为服务器不接受PEM证书。我无法使用PEM证书在Firefox中连接到服务器。”
httplib的HTTPSConnection是否应该支持PCKS#12证书? (也就是说,pfx文件。)如果是这样,为什么openSSL试图将其加载到PEM库中?我做错了吗?
欢迎任何建议。
编辑:证书文件包含证书和私钥,这就是我为HTTPSConnection的key_file和cert_file参数提供相同文件名的原因。
答案 0 :(得分:4)
在openSSL邮件列表中,我与Mounir Idrassi聊天。他指出openSSL确实支持PKCS#12文件,并且 - 基于我收到的错误消息 - 似乎httplib正在调用错误的函数来加载密钥。
用他的话说:
“关于您所获得的错误,您正在使用的phython模块通过为其提供PKCS#12文件名来调用SSL_CTX_use_PrivateKey_file。这不是因为SSL_CTX_use_PrivateKey_file只接受两种格式:SSL_FILETYPE_PEM和SSL_FILETYPE_ASN1。”< / p>
(我给httplib PKCS#12文件名作为密钥文件,因为这种文件格式包括同一文件中的证书和私钥。)
“为了纠正这个问题,你有两个解决方案: - 使用PEM文件中的私钥提供python模块。 - 或修改此python模块的源代码,以便使用上面提到的PKCS#12函数将私钥解压缩为EVP_PKEY,然后调用SSL_use_PrivateKey而不是SSL_CTX_use_PrivateKey_file,以及SSL_use_certificate来设置相关证书。“ p>
(我尝试了前者而无法让它发挥作用。并不一定意味着它不起作用;只是我无法做到。)
答案 1 :(得分:4)
这并不奇怪。 Python库参考文档非常清楚这一点。来自http://docs.python.org/library/httplib.html:
类httplib。 HTTPSConnection (host [,port [,key_file [,cert_file [,strict [,timeout [,source_address]]]]]])
HTTPConnection的子类,它使用SSL与安全服务器进行通信。默认端口为443.key_file是包含私钥的 PEM格式 文件的名称。 cert_file是 PEM格式的 证书链文件。