2012-07-20 183 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