Python請求引發SSLError


8 Answers

從請求有關SSL驗證的文檔

請求可以驗證HTTPS請求的SSL證書,就像Web瀏覽器一樣。 要檢查主機的SSL證書,可以使用verify參數:

>>> requests.get('https://kennethreitz.com', verify=True)

如果您不想驗證您的SSL證書,請將verify=False

Question

我正在研究一個涉及CAS,jspring安全檢查,重定向等的簡單腳本。我想使用Kenneth Reitz的python請求,因為它是一項偉大的工作! 但是,CAS需要通過SSL進行驗證,因此我必須先通過該步驟。 我不知道Python要求的是什麼? 這個SSL證書應該放在哪裡?

Traceback (most recent call last):
  File "./test.py", line 24, in <module>
  response = requests.get(url1, headers=headers)
  File "build/bdist.linux-x86_64/egg/requests/api.py", line 52, in get
  File "build/bdist.linux-x86_64/egg/requests/api.py", line 40, in request
  File "build/bdist.linux-x86_64/egg/requests/sessions.py", line 209, in request 
  File "build/bdist.linux-x86_64/egg/requests/models.py", line 624, in send
  File "build/bdist.linux-x86_64/egg/requests/models.py", line 300, in _build_response
  File "build/bdist.linux-x86_64/egg/requests/models.py", line 611, in send
requests.exceptions.SSLError: [Errno 1] _ssl.c:503: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed



如果請求調用被隱藏在代碼的深處,並且您不想安裝服務器證書,那麼僅僅為了調試目的 ,可以對請求進行monkeypatch:

import requests.api
import warnings


def requestspatch(method, url, **kwargs):
    kwargs['verify'] = False
    return _origcall(method, url, **kwargs)

_origcall = requests.api.request
requests.api.request = requestspatch
warnings.warn('Pathched requests: SSL verification disabled!')

切勿在生產中使用!




$ pip install -U requests[security]

  • 測試Python 2.7.6 @ Ubuntu 14.04.4 LTS
  • 測試Python 2.7.5 @ MacOSX 10.9.5(小牛隊)

當此問題已打開(2012-05)時,請求版本為0.13.1。 在版本2.4.1(2014-09)中引入了“安全”附加功能,使用certifi包(如果可用)。

現在(2016-09)主版本是2.11.1, 沒有 verify=False ,效果很好。 無需使用requests.get(url, verify=False) ,如果安裝了requests[security]額外的。




如果你有一個依賴於requests的庫,並且你不能修改驗證路徑(就像使用pyvmomi ),那麼你必須找到與請求捆綁在一起的cacert.pem並在那裡附加你的CA. 以下是查找cacert.pem位置的一般方法:

視窗

C:\>python -c "import requests; print requests.certs.where()"
c:\Python27\lib\site-packages\requests-2.8.1-py2.7.egg\requests\cacert.pem

Linux的

#  (py2.7.5,requests 2.7.0, verify not enforced)
root@host:~/# python -c "import requests; print requests.certs.where()"
/usr/lib/python2.7/dist-packages/certifi/cacert.pem

#  (py2.7.10, verify enforced)
root@host:~/# python -c "import requests; print requests.certs.where()"
/usr/local/lib/python2.7/dist-packages/requests/cacert.pem

順便說一句。 @ requests-devs,將你自己的cacerts與請求綁定在一起真的很煩人......特別是你似乎並沒有首先使用系統ca store,而這在任何地方都沒有記錄。

更新

在使用庫並且無法控制ca-bundle位置的情況下,您還可以明確地將ca-bundle位置設置為您的主機範圍的ca-bundle:

REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-bundle.crt python -c "import requests; requests.get('https://somesite.com';)"



經過幾個小時的調試後,我只能使用下列軟件包來實現這個功能:

requests[security]==2.7.0  # not 2.18.1
cryptography==1.9  # not 2.0

使用OpenSSL 1.0.2g 1 Mar 2016

如果沒有這些包, verify=False不起作用。

我希望這可以幫助別人。




我遇到了同樣的問題。 原來我沒有在我的服務器上安裝中間證書(只需將它附加到證書的底部,如下所示)。

https://www.digicert.com/ssl-support/pem-ssl-creation.htm

確保你已經安裝了ca-certificates包:

sudo apt-get install ca-certificates

更新時間也可能解決這個問題:

sudo apt-get install ntpdate
sudo ntpdate -u ntp.ubuntu.com

如果您使用的是自簽名證書,則可能需要手動將其添加到系統中。




我使用gspread面對同樣的問題,這些命令適用於我:

sudo pip uninstall -y certifi
sudo pip install certifi==2015.04.28






正如@Rafael Almeida所提到的,您遇到的問題是由不可信的SSL證書引起的。 在我的情況下,SSL證書不受我的服務器的信任。 為了在不影響安全性的情況下解決這個問題,我下載了證書並將其安裝到服務器上(只需雙擊.crt文件,然後安裝證書...)。




Related