2012-09-12 35 views
0

我正在嘗試編寫一個https服務器和客戶端。我創建了一個CA,以及用於測試的私鑰和自簽名證書。SSL驗證python服務器/ python

這裏是我的測試服務器:

#!/usr/bin/env python 

import socket, os 
from SocketServer import BaseServer 
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler 
from SimpleHTTPServer import SimpleHTTPRequestHandler 
from OpenSSL import SSL 

CERTIFICATE_PATH = os.getcwd() + '/CA/cacert.pem' 
KEY_PATH = os.getcwd() + '/CA/private/key.pem' 


class SecureHTTPServer(HTTPServer): 
    def __init__(self, server_address, HandlerClass): 
     BaseServer.__init__(self, server_address, HandlerClass) 
     ctx = SSL.Context(SSL.SSLv23_METHOD) 

     ctx.use_privatekey_file(KEY_PATH) 
     ctx.use_certificate_file(CERTIFICATE_PATH) 

     self.socket = SSL.Connection(ctx, socket.socket(self.address_family, self.socket_type)) 

     self.server_bind() 
     self.server_activate() 

class MemberUpdateHandler(SimpleHTTPRequestHandler): 
    def setup(self): 
     self.connection = self.request 
     self.rfile = socket._fileobject(self.request, "rb", self.rbufsize) 
     self.wfile = socket._fileobject(self.request, "wb", self.wbufsize) 

    def do_GET(self): 
     try: 
      print 'path:', self.path 
      print self.path.endswith('.txt') 
      if self.path.endswith('.txt'): 
       self.send_response(200) 
       self.send_header('Content-type', 'text/html') 
       self.end_headers() 
       self.wfile.write("successful") 
       return 
      else: 
       self.send_response(200) 
       self.send_header('Content-type', 'text/html') 
       self.end_headers() 
       self.wfile.write("not successful") 
     except IOError: 
      self.send_error(404, 'What you talking about willis?') 


def test(HandlerClass = MemberUpdateHandler, 
     ServerClass = SecureHTTPServer): 
    server_address = ('', 4242) 
    httpd = ServerClass(server_address, HandlerClass) 
    sa = httpd.socket.getsockname() 
    print "serving HTTPS on:", sa[0], "port:", sa[1], "..." 
    httpd.serve_forever() 

if __name__ == '__main__': 
    test() 

和我簡單的客戶端:

#!/usr/bin/env python 

import os 
import httplib 
import socket 

KEY_FILE = os.getcwd() + '/CA/private/key.pem' 
CERT_FILE = os.getcwd() + '/CA/certs/01.pem' 
GET = "GET" 


conn = httplib.HTTPSConnection('0.0.0.0', '4242', cert_file = CERT_FILE) 

conn.request(GET, "/this.txt") 
response = conn.getresponse() 
print response.status, response.reason, response.read() 

conn.close() 

我的問題出現了,當我嘗試添加 cert_file中= cert_file中 如果我從呼叫刪除, 有用。但我認爲我沒有得到我想要的驗證。

這裏試圖我得到的錯誤時:

在服務器端:

Exception happened during processing of request from ('127.0.0.1', 55283) 
Traceback (most recent call last): 
File "/usr/lib/python2.6/SocketServer.py", line 281, in _handle_request_noblock 
    self.process_request(request, client_address) 
File "/usr/lib/python2.6/SocketServer.py", line 307, in process_request 
    self.finish_request(request, client_address) 
File "/usr/lib/python2.6/SocketServer.py", line 320, in finish_request 
    self.RequestHandlerClass(request, client_address, self) 
File "/usr/lib/python2.6/SocketServer.py", line 615, in __init__ 
    self.handle() 
File "/usr/lib/python2.6/BaseHTTPServer.py", line 329, in handle 
    self.handle_one_request() 
File "/usr/lib/python2.6/BaseHTTPServer.py", line 312, in handle_one_request 
self.raw_requestline = self.rfile.readline() 
File "/usr/lib/python2.6/socket.py", line 406, in readline 
data = self._sock.recv(self._rbufsize) 
Error: [('SSL routines', 'SSL23_READ', 'ssl handshake failure')] 

並從客戶端:

File "HTTPSClient.py", line 19, in <module> 
conn.request(GET, "/this.txt") 
File "/usr/lib/python2.6/httplib.py", line 910, in request 
self._send_request(method, url, body, headers) 
File "/usr/lib/python2.6/httplib.py", line 947, in _send_request 
self.endheaders() 
File "/usr/lib/python2.6/httplib.py", line 904, in endheaders 
self._send_output() 
File "/usr/lib/python2.6/httplib.py", line 776, in _send_output 
self.send(msg) 
File "/usr/lib/python2.6/httplib.py", line 735, in send 
self.connect() 
File "/usr/lib/python2.6/httplib.py", line 1112, in connect 
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file) 
File "/usr/lib/python2.6/ssl.py", line 350, in wrap_socket 
suppress_ragged_eofs=suppress_ragged_eofs) 
File "/usr/lib/python2.6/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 

我應該什麼要發送的文件嗎?我有一個CA證書,一個簽名證書和一個私鑰。我所能找到的文檔相當稀少。

+0

我開始想,我根本誤解了這整個事情是如何工作的。 – Lunchbox

回答

2

在此基礎上[文件] [1]

class httplib.HTTPSConnection(host[, port[, key_file[, cert_file[, strict[, timeout[, source_address]]]]]]) 
A subclass of HTTPConnection that uses SSL for communication with secure servers. Default port is 443. key_file is the name of a PEM formatted file that contains your private key. cert_file is a PEM formatted certificate chain file. 

**Warning This does not do any verification of the server’s certificate.** 

我不知道(不與Python經歷),但我相信KEY_FILE和cert_file中是客戶端身份驗證。

而且你可以看看這個鏈接有關證書驗證: http://code.activestate.com/recipes/577548-https-httplib-client-connection-with-certificate-v/

+0

你看起來是正確的。謝謝。 – Lunchbox