2010-04-13 65 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

相關問題