[英]Python requests.post certificate verify fails
我有一個 python 應用程序,它通過 HTTPS 連接到網頁 (wikis.xxx.yyy) 以從中檢索和解析數據。 鑒於所需的證書鏈在瀏覽器中,我可以瀏覽網頁(我的系統使用 Ubuntu 14.04 LTS)。
$ python --version
Python 2.7.6
連接調用:
data = requests.post(URL, data=payload)
失敗並出現以下錯誤:
requests.exceptions.SSLError: [Errno bad handshake] [('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')]
我不能使用verify=False
因為如果我這樣做,我會收到此錯誤:
/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html InsecureRequestWarning)
我嘗試將驗證中的證書作為客戶端證書( http://docs.python-requests.org/en/latest/user/advanced/ )傳遞: data = requests.post(radio_status_URL, data=payload, verify="/home/user/.cert/foo.pem")
但它沒有連接並且實際上沒有返回任何錯誤。
考慮到我需要將證書鏈安裝到受信任的 Ubuntu CA 存儲中,我按照以下說明操作: https ://askubuntu.com/questions/73287/how-do-i-install-a-root-certificate foo.cert我添加的證書具有以下格式:
-----BEGIN CERTIFICATE-----
<....>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<....>
-----END CERTIFICATE-----
使用 openssl 我可以看到證書鏈沒問題,我可以連接到 wikis.xxx.yyy :-)
$ openssl s_client -CApath ~/.cert/ -connect wikis.xxx.yyy:443
CONNECTED(00000003)
depth=2 DC = local, DC = windows, CN = RIM Root CA MCA01YKF
verify return:1
depth=1 DC = net, DC = rim, CN = RIM Subordinate CA MCA03YKF
verify return:1
depth=0 C = CA, ST = Ontario, L = Waterloo, O = BlackBerry, OU = BTS Operations, CN = wikis.xxx.yyy, emailAddress = no-reply@xxx.yyy
verify return:1
---
Certificate chain
0 s:/C=CA/ST=Ontario/L=Waterloo/O=BlackBerry/OU=BTS Operations/CN=wikis.xxx.yyy/emailAddress=no-reply@xxx.yyy
i:/DC=net/DC=rim/CN=RIM Subordinate CA MCA03YKF
---
Server certificate
-----BEGIN CERTIFICATE-----
<...>
-----END CERTIFICATE-----
subject=/C=CA/ST=Ontario/L=Waterloo/O=BlackBerry/OU=BTS Operations/CN=wikis.xxx.yyy/emailAddress=no-reply@xxx.yyy
issuer=/DC=net/DC=rim/CN=RIM Subordinate CA MCA03YKF
---
No client certificate CA names sent
---
SSL handshake has read 1810 bytes and written 609 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1.2
Cipher : RC4-SHA
Session-ID: FFD3D3EAC3807427D2D5E5BB2D70F064E2BB14218A368676A3225FBC5E5F1078
Session-ID-ctx:
Master-Key: 930FBFB110BFC861E06C6A27DEBB15C2524A86F7EFC56693F4E52BA33F0AD236E5182169039909EC1BB3DE89C4C96B2B
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1442413894
Timeout : 300 (sec)
Verify return code: 0 (ok)
所以它可以工作並給出 0 的 ret 代碼。不幸的是,python 沒有做同樣的事情,我不知道如何連接 :-(
我該如何解決?
從您的上一個測試案例中可以看出 wikis.xxx.yyy 使用 TLSv1.2,但是 Requests 模塊需要稍作修改才能使用它。
請參考這篇文章: https : //lukasa.co.uk/2013/01/Choosing_SSL_Version_In_Requests/
有一個很好的插件可以做到這一點:https ://toolbelt.readthedocs.org/en/latest/user.html#ssladapter
順便說一句,如果您安裝了 urllib3,請求將使用它,但 urllib3 直到現在才支持 TLS v1.2。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.