为Python Web Server增加HTTPs双向验证

业务背景

最近在用Python实现一个提供Http接口的Server,因为该Server会被安装在远程的机器,为了确保二者之间通信的安全,需要提供Https,切二者为双向验证。

技术背景

常规的Https验证是单向的,例如浏览器访问Web server,Web server会提供自己的证书,浏览器需要验证该证书的合法性,一般来说,该证书需要被权威CA(Certificate Authority)签名。如果是自签名证书,就需要浏览器提前把该证书加入自己的信任链。而此种情形下,Server是不需要关心客户端的身份,客户端的身份由后续的业务逻辑保证。

而我们的业务需求则是需要Server在接受客户端连接时就能够确认客户端是否有权利访问,这就需要利用Https的客户端验证技术。其实从技术层面该技术没有什么特殊的,只是这种场景在实际中比较少见,所以知道的人不多。下面就如何在Python中实现详细介绍。

技术实现

Server

import BaseHTTPServer, SimpleHTTPServer  
import ssl

httpd = BaseHTTPServer.HTTPServer(('localhost', 4433), SimpleHTTPServer.SimpleHTTPRequestHandler)  
httpd.socket = ssl.wrap_socket(httpd.socket, certfile='server.crt', server_side=True,  
                               keyfile='server.key',
                               cert_reqs=ssl.CERT_REQUIRED,
                               ca_certs='client.crt'
                               )
httpd.serve_forever()

Client

import requests  
rsp=requests.get('https://localhost:4433', verify=False,  
                 cert=('client.crt', 'client.key')
                 )
print rsp.status_code  
print rsp.text