簡體   English   中英

如何獲得 Python 請求以信任自簽名 SSL 證書?

[英]How to get Python requests to trust a self signed SSL certificate?

import requests
data = {'foo':'bar'}
url = 'https://foo.com/bar'
r = requests.post(url, data=data)

如果 URL 使用自簽名證書,則失敗並顯示

requests.exceptions.SSLError: [Errno 1] _ssl.c:507: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

我知道我可以將False傳遞給verify參數,如下所示:

r = requests.post(url, data=data, verify=False)

但是,我想做的是將請求指向磁盤上公鑰的副本,並告訴它信任該證書。

嘗試:

r = requests.post(url, data=data, verify='/path/to/public_key.pem')

使用verify參數,您可以提供自定義證書頒發機構包

requests.get(url, verify=path_to_bundle_file)

文檔

您可以使用受信任的 CA 證書傳遞verify CA_BUNDLE 文件的路徑。 這個受信任的 CA 列表也可以通過 REQUESTS_CA_BUNDLE 環境變量指定。

最簡單的方法是導出指向您的私有證書頒發機構或特定證書包的變量REQUESTS_CA_BUNDLE 在命令行上,您可以按如下方式執行此操作:

export REQUESTS_CA_BUNDLE=/path/to/your/certificate.pem
python script.py

如果您擁有證書頒發機構並且不想每次都鍵入export ,則可以將REQUESTS_CA_BUNDLE添加到您的~/.bash_profile ,如下所示:

echo "export REQUESTS_CA_BUNDLE=/path/to/your/certificate.pem" >> ~/.bash_profile ; source ~/.bash_profile

需要多個證書的情況如下解決:將多個根 pem 文件 myCert-A-Root.pem 和 myCert-B-Root.pem 連接到一個文件中。 然后將請求 REQUESTS_CA_BUNDLE var 設置為我的 ./.bash_profile 中的那個文件。

$ cp myCert-A-Root.pem ca_roots.pem
$ cat myCert-B-Root.pem >> ca_roots.pem
$ echo "export REQUESTS_CA_BUNDLE=~/PATH_TO/CA_CHAIN/ca_roots.pem" >> ~/.bash_profile ; source ~/.bash_profile

設置export SSL_CERT_FILE=/path/file.crt應該可以完成這項工作。

如果您像我一樣在公司網絡防火牆后面,請詢問您的網絡管理員您的公司證書在哪里,然后:

import os
os.environ["REQUESTS_CA_BUNDLE"] = 'path/to/corporate/cert.pem'
os.environ["SSL_CERT_FILE"] = 'path/to/corporate/cert.pem'

這解決了我在 requests 和 openssl 中遇到的問題。

這個問題的所有答案都指向相同的路徑:獲取 PEM 文件,但他們沒有告訴您如何從網站本身獲取它。

如果您信任該網站(例如在內部公司服務器上),則從網站本身獲取 PEM 文件是一個有效的選擇。 如果您信任該網站,為什么要這樣做? 您應該這樣做,因為它有助於保護您自己和他人免於在不安全的站點上無意中重復使用您的代碼。

以下是獲取 PEM 文件的方法。

  1. 點擊網址旁邊的鎖。 點擊鎖<\/a>

  2. 導航到可以查看證書的位置並打開證書。

  3. 下載 PEM CERT 鏈。

  4. 將 .PEM 文件放在您的腳本可以訪問的地方,並在您的requests<\/code>調用中嘗試verify=r"path\\to\\pem_chain.pem"<\/code> 。

如果有人碰巧來到這里(就像我一樣)希望為 httplib2 添加 CA(在我的例子中是 Charles Proxy),看起來您可以將它附加到 python 包中包含的cacerts.txt文件中。

例如:

cat ~/Desktop/charles-ssl-proxying-certificate.pem >> /usr/local/google-cloud-sdk/lib/third_party/httplib2/cacerts.txt

其他解決方案中引用的環境變量似乎是特定於請求的,並且在我的測試中沒有被 httplib2 選取。

你可以試試:

settings = s.merge_environment_settings(prepped.url, None, None, None, None)

您可以在此處閱讀更多信息: http : //docs.python-requests.org/en/master/user/advanced/

在開發環境中,在帶有 Python 3.8 的 Mac 上使用 Poetry 作為虛擬環境提供程序我使用這個答案https://stackoverflow.com/a/42982144/15484549作為基礎,並將我的自簽名根證書的內容附加到證書cacert.pem 文件。

詳細步驟:

cd project_folder
poetry add requests
# or if you use something else, make sure certifi is among the dependencies
poetry shell
python
>>> import certifi
>>> certifi.where()
/path/to/the/certifi/cacert.pem
>>> exit()
cat /path/to/self-signed-root-cert.pem >> /path/to/the/certifi/cacert.pem
python the_script_you_want_to_run.py

我知道這是一個舊線程。 但是,我最近遇到了這個問題。 我的 python 請求代碼不接受自簽名證書,但 curl 接受。 原來 python 請求對自簽名證書非常嚴格。 它需要是根 CA 證書。 換句話說,

基本約束:CA:TRUE

密鑰用途:數字簽名、不可否認性、密鑰加密、證書簽名

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM