2010-04-13 90 views
5

我想使用httplib的HTTPSConnection进行客户端验证,使用PKCS#12证书。我知道证书是好的,因为我可以连接到在MSIE和Firefox中使用它的服务器。使用httlib的HTTPSConnection与PKCS#12证书时出错

这是我的连接功能(证书包含私钥)。我已经缩减下来,只是最基础的:

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中连接到它。)

当我尝试使用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参数提供相同的文件名。

回答

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。“

(我给httplib的的PKCS#12文件名作为关键字的文件,因为这个文件格式包括了证书,并在同一个文件中的私钥。)

“为了解决这个问题,你有两个解决方案: - 在PEM文件中用私钥提供python模块 - 或者修改这个python模块的源代码,以便使用我上面提到的PKCS#12函数来提取私钥作为EVP_PKEY,然后调用SSL_use_PrivateKey而不是SSL_CTX_use_PrivateKey_file以及SSL_use_certificate来设置关联的证书。“

(我试过前者无法得到它的工作并不一定意味着它不会工作;只有我是不是能。)

4

这并不奇怪。Python库参考文档是关于这个很清楚从http://docs.python.org/library/httplib.html

类httplib的HTTPSConnection(主机[,端口[,KEY_FILE [,cert_file中[,严格[,超时[,source_address]]]。 ]]])

使用SSL与安全服务器进行通信的HTTPConnection的子类。默认端口是443. key_file是PEM格式的名称包含您的私钥的文件。 cert_file是PEM格式证书链文件。

+0

+1对于RTFM。去年我在做这件事的时候去了哪里? :) – 2011-12-21 14:39:10

+0

嗨雷米,我有点慢下来---) - 我是相当新的SO。刚刚发现您的帖子搜索类似的错误字符串。原来,我只是在调用链的某个地方歪曲了参数顺序,并没有将关键路径传递给httplib。 – Blairo 2011-12-21 23:47:50

相关问题