tornado下https配置

問題背景

愈來愈多的網站已經支持https,相比於http更安全。尤爲有的開發網站只支持https,例如微信公衆平臺。
這裏暫時不提tornado如何搭建https服務,回頭有時間再記一下。python

SSLError

能夠用AsyncHTTPClient發送一個簡單的https請求git

https_url = "https://path"      
https_client = AsyncHTTPClient()
response = yield YieldTask(token_client.fetch, access_token_url)

結果出現了以下問題github

ssl.SSLError: [Errno 1] _ssl.c:510: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failedweb

參考tornado rejects valid SSL certificates安全

這個緣由是由於證書設置不正確,那麼咱們能夠經過下面的操做給AsyncHTTPClient設置證書。微信

import certifi
 AsyncHTTPClient.configure(None, defaults=dict(ca_certs=certifi.where()))

可是這個設置之後,會發現雖然不報錯了,可是請求仍是會失敗,錯誤緣由依然是certificate verify failed微信公衆平臺

查看了certifi的主頁
certifiless

發現官方也給出瞭解釋:tornado

Unfortunately, old versions of OpenSSL (less than 1.0.2) sometimes
fail to validate certificate chains that use the strong roots. For
this reason, if you fail to validate a certificate using the
certifi.where() mechanism, you can intentionally re-add the 1024-bit
roots back into your bundle by calling certifi.old_where() instead.
This is not recommended in production: if at all possible you should
upgrade to a newer OpenSSL. However, if you have no other option, this
may work for you.fetch

其實大概就是由於openssl的老版本(地域1.0.2)用的校驗是strong roots(指的是隻信任了少部分ca嗎?我也沒太懂)。總之,有好幾個解決方法:
一、換老版本的certifi來解決(由於老版本的certifi證書比較老,跟老版本的openssl正好合得來),可是這種方法不是很是好,目前看網上用的是certifi==2015.04.28版本,這個版本也沒有certifi.old_where(),由於自己就是老的……

二、就用新版本的certifi,可是驗證時用certifi.old_where()下面的證書來進行配置

import certifi
AsyncHTTPClient.configure(None, defaults=dict(ca_certs=certifi.old_where()))

三、升級python版本到2.7.9以上,由於這以後,python進行https請求時,不用再經過certifi來配置,而是已經內置了相關的證書。

四、升級openssl到1.0.2及以上。

推薦升級openssl或者Python版本,若是由於環境限制,實在沒辦法的話用old_where也行。

相關文章
相關標籤/搜索