我寫了一個簡單的網絡服務器&客戶端與Python,以下是我的代碼。我想實現HTTPS,因爲我使用的是標準SSL庫。我正在使用Python 2.7.3。我生成了證書文件並自行簽名。所以我有.crt和.key文件,我用它來綁定套接字。HTTPS服務器與Python
當我從瀏覽器中瀏覽它時,出現證書自簽名的異常錯誤,我必須將其添加到例外。然後它工作。
代碼我的服務器的:
import BaseHTTPServer
import urlparse
import urllib
import SocketServer
import threading
import ssl
HOST_NAME = 'localhost'
PORT_NUMBER = 8089
class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_HEAD(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
if self.path == '/get/':
self.wfile.write('On /get/')
return
self.wfile.write('On root')
return
def do_POST(self):
pass
class ThreadedHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
pass
if __name__ == '__main__':
httpd = BaseHTTPServer.HTTPServer((HOST_NAME, PORT_NUMBER), Handler)
httpd.socket = ssl.wrap_socket (httpd.socket, keyfile='my_key.key', certfile='my_cert.crt', server_side=True)
try:
httpd.serve_forever()
except KeyboardInterrupt:
httpd.server_close()
print "Server Stopped - %s:%s" % (HOST_NAME, PORT_NUMBER)
不過,我想使用的請求模塊,當我提供與請求.crt文件,我得到以下 錯誤:
requests.get('https://localhost:8089', verify=True)
#requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
requests.get('https://localhost:8089', verify='my_cert.crt')
#requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
requests.get('https://localhost:8089', cert='my_crt.crt')
#requests.exceptions.SSLError: [Errno 336265225] _ssl.c:351: error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib
requests.get('https://localhost:8089', cert=('my_crt.crt', 'my_key.key'))
# requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
requests.get('https://localhost:8089', verify=False)
#<Response [200]>
1)爲什麼我得到這個錯誤?我當然不想使用'verify = False'。我想驗證客戶端的證書 。
2)(假設我得到使它工作)如果我執行cert_reqs = CERT_REQUIRED改變:
httpd.socket = ssl.wrap_socket (httpd.socket, keyfile='my_key.key', certfile='my_cert.crt', cert_reqs=CERT_REQUIRED, server_side=True)
那麼它僅僅意味着誰擁有我的證書文件(my_cert.crt人)將能發送請求並得到迴應的人和不會的人,將無法?
將您的certfile與請求提供的文件進行比較,確保它們都是相同的格式。這是最明顯的失敗原因。 – Lukasa
他們是一樣的。事實上,我從同一個文件夾運行客戶端和服務器,他們使用相同的密鑰 – avi
這不是我的意思。請求提供一個默認的'cacert.pem'文件,你可以在這裏看到(https://github.com/kennethreitz/requests/blob/master/requests/cacert.pem)。我的意思是你應該確保這裏的格式與你的certfile的格式相匹配。 – Lukasa