2012-07-20 131 views
2

我試圖通過使用身份驗證的HTTPS連接建立成功的通信。我在Ubuntu 12.04上使用Python 2.7 w/Django 1.4。SSL連接使用Python的.pem證書

我遵循的API文檔對認證有特定的要求。包括您將在下面找到併發送證書信息的Authentication標題。

這是代碼:

import httplib 
import base64 

HOST = 'some.host.com' 
API_URL = '/some/api/path' 

username = '1234' 
password = '5678' 

auth_value = base64.b64encode('WS{0}._.1:{1}'.format(username, password)) 
path = os.path.join(os.path.dirname(__file__), 'keys/') 
pem_file = '{0}WS{1}._.1.pem'.format(path, username) 

xml_string = '<some><xml></xml><stuff></stuff></some>' 

headers = { 'User-Agent'  : 'Rico', 
      'Content-type' : 'text/xml', 
      'Authorization' : 'Basic {0}'.format(auth_value), 
      } 



conn = httplib.HTTPSConnection(HOST, cert_file = pem_file) 
conn.putrequest("POST", API_URL, xml_string, headers) 
response = conn.getresponse() 

,我發現了以下錯誤:

Traceback: 
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response 
    111.       response = callback(request, *callback_args, **callback_kwargs) 
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/csrf.py" in wrapped_view 
    77.   return view_func(*args, **kwargs) 
File "/home/tokeniz/tokeniz/gateway_interface/views.py" in processPayment 
    37.   processCreditCard = ProcessCreditCard(token, postHandling) 
File "/home/tokeniz/tokeniz/gateway_interface/credit_card_handling.py" in __init__ 
    75.    self.processGateway() 
File "/home/tokeniz/tokeniz/gateway_interface/credit_card_handling.py" in processGateway 
    95.   gateway = Gateway(self) 
File "/home/tokeniz/tokeniz/gateway_interface/first_data.py" in __init__ 
    37.   self.postInfo() 
File "/home/tokeniz/tokeniz/gateway_interface/first_data.py" in postInfo 
    245.   response = conn.getresponse() 
File "/usr/lib/python2.7/httplib.py" in getresponse 
    1018.    raise ResponseNotReady() 

Exception Type: ResponseNotReady at /processPayment/ 
Exception Value: 

爲什麼會出現這個錯誤?

更新1: 我一直在使用他們給我的.pem文件(鏈接點網關),但已經讀過證書文件應該同時包含證書和RSA私鑰。那是對的嗎?我試圖發送一個.pem文件含有並收到以下錯誤:

Traceback: 
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response 
    111.       response = callback(request, *callback_args, **callback_kwargs) 
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/csrf.py" in wrapped_view 
    77.   return view_func(*args, **kwargs) 
File "/home/tokeniz/tokeniz/gateway_interface/views.py" in processPayment 
    37.   processCreditCard = ProcessCreditCard(token, postHandling) 
File "/home/tokeniz/tokeniz/gateway_interface/credit_card_handling.py" in __init__ 
    75.    self.processGateway() 
File "/home/tokeniz/tokeniz/gateway_interface/credit_card_handling.py" in processGateway 
    95.   gateway = Gateway(self) 
File "/home/tokeniz/tokeniz/gateway_interface/first_data.py" in __init__ 
    37.   self.postInfo() 
File "/home/tokeniz/tokeniz/gateway_interface/first_data.py" in postInfo 
    251.   conn.request('POST', self.API_URL, self.xml_string, headers) 
File "/usr/lib/python2.7/httplib.py" in request 
    958.   self._send_request(method, url, body, headers) 
File "/usr/lib/python2.7/httplib.py" in _send_request 
    992.   self.endheaders(body) 
File "/usr/lib/python2.7/httplib.py" in endheaders 
    954.   self._send_output(message_body) 
File "/usr/lib/python2.7/httplib.py" in _send_output 
    814.   self.send(msg) 
File "/usr/lib/python2.7/httplib.py" in send 
    776.     self.connect() 
File "/usr/lib/python2.7/httplib.py" in connect 
    1161.    self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file) 
File "/usr/lib/python2.7/ssl.py" in wrap_socket 
    381.      ciphers=ciphers) 
File "/usr/lib/python2.7/ssl.py" in __init__ 
    141.           ciphers) 

Exception Type: SSLError at /processPayment/ 
Exception Value: [Errno 336265225] _ssl.c:351: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib 

我不能說,如果這是向前或向後的一步。

更新2: 我試圖在創建連接對象時傳遞證書文件和密鑰文件。

conn = httplib.HTTPSConnection(HOST, cert_file = pem_file, key_file = key_file) 

我得到以下錯誤:

Traceback: 
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response 
    111.       response = callback(request, *callback_args, **callback_kwargs) 
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/csrf.py" in wrapped_view 
    77.   return view_func(*args, **kwargs) 
File "/home/tokeniz/tokeniz/gateway_interface/views.py" in processPayment 
    37.   processCreditCard = ProcessCreditCard(token, postHandling) 
File "/home/tokeniz/tokeniz/gateway_interface/credit_card_handling.py" in __init__ 
    75.    self.processGateway() 
File "/home/tokeniz/tokeniz/gateway_interface/credit_card_handling.py" in processGateway 
    95.   gateway = Gateway(self) 
File "/home/tokeniz/tokeniz/gateway_interface/first_data.py" in __init__ 
    37.   self.postInfo() 
File "/home/tokeniz/tokeniz/gateway_interface/first_data.py" in postInfo 
    252.   conn.request('POST', self.API_URL, self.xml_string, headers) 
File "/usr/lib/python2.7/httplib.py" in request 
    958.   self._send_request(method, url, body, headers) 
File "/usr/lib/python2.7/httplib.py" in _send_request 
    992.   self.endheaders(body) 
File "/usr/lib/python2.7/httplib.py" in endheaders 
    954.   self._send_output(message_body) 
File "/usr/lib/python2.7/httplib.py" in _send_output 
    814.   self.send(msg) 
File "/usr/lib/python2.7/httplib.py" in send 
    776.     self.connect() 
File "/usr/lib/python2.7/httplib.py" in connect 
    1161.    self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file) 
File "/usr/lib/python2.7/ssl.py" in wrap_socket 
    381.      ciphers=ciphers) 
File "/usr/lib/python2.7/ssl.py" in __init__ 
    141.           ciphers) 

Exception Type: SSLError at /processPayment/ 
Exception Value: [Errno 336265225] _ssl.c:351: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib 

如果我嘗試並結合證書文件和密鑰文件並把它作爲我收到同樣的錯誤證書說法。

回答

6

似乎Python中的某些「更高級別」庫沒有裝備來處理這種認證連接。經過多天的嘗試,我終於能夠想出一個解決方案進入套接字級別。

host = 'some.host.com' 
service = '/some/api/path' 
port = 443 

# Build the authorization info 
username = '1234' 
password = '5678' 
path = '/path/to/key/files/' 
pem_file = '{0}WS{1}._.1.pem'.format(path, username) 
key_file = '{0}WS{1}._.1.key'.format(path, username) 
auth = base64.b64encode('WS{0}._.1:{1}'.format(username, password)) 

## Create the header 
http_header = "POST {0} HTTP/1.0\nHost: {1}\nContent-Type: text/xml\nAuthorization: Basic {2}\nContent-Length: {3}\n\n" 
req = http_header.format(service, host, auth, len(xml_string)) + xml_string 

## Create the socket 
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
conn = ssl.wrap_socket(sock, keyfile = key_file, certfile = pem_file) 
conn.connect((host, port)) 
conn.send(req) 

response = '' 
while True: 
    resp = conn.recv() 
    response += resp 

    if (resp == ''): 
     break 

我希望有人認爲這有用。這個特定的實現是用Python與Link Point Gateway進行接口(不支持First Data(Link Point))。談論整個項目的噩夢。 haha

無論如何,對於使用鏈接點時遇到問題的任何人,請注意他們提供的.key文件不足以在Python中創建連接。

openssl rsa -in orig_file.key -out new_file.key

然後使用new_file.key代替。

+1

幹得好,但我不明白,這是什麼問題,爲什麼這個解決了它? – securecurve 2013-09-30 05:59:33

相關問題