簡體   English   中英

Python 3 帶有自簽名證書的 urllib

[英]Python 3 urllib with self-signed certificates

我正在嘗試使用 Python 從內部服務器下載一些數據。由於它是內部服務器,因此它使用自簽名證書。 (我們不想為永遠不會出現在“野外”的服務器支付 Verisign 費用。)代碼的 Python 2.6 版本運行良好。

response = urllib2.urlopen(URL)
data = csv.reader(response)

我現在正在嘗試更新到 Python 3.4(長話短說,不要問。)但是,使用 Python 3 的 urllib 失敗:

response = urllib.request.urlopen(URL)

它會拋出 CERTIFICATE_VERIFY_FAILED 錯誤。

urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)>

在閱讀 web 時,顯然 Python 2.6 urllib2 不會費心驗證證書。 某些版本的 urllib 允許將“verify=False”傳遞給方法簽名,但這在 Python 3.4 中似乎不起作用。

有誰知道我該如何解決這個問題? 由於公司安全准則,我想避免使用請求 package。

使用以下內容禁用 URL 的 SSL 證書驗證

import ssl
myssl = ssl.create_default_context();
myssl.check_hostname=False
myssl.verify_mode=ssl.CERT_NONE
urlopen("URL",context=myssl)

使用以下內容禁用所有 URL 的 SSL 證書驗證

 ssl._create_default_https_context = ssl._create_unverified_context
 urlopen("URL");

urllib.request.urlopen有一個接受SSLContext對象的上下文關鍵字參數。 因此,傳遞一個.verify_mode設置為ssl.CERT_NONESSLContext對象,即SSLContext.verify_mode = ssl.CERT_NONE應該等於verify=False

使用urllib3

import urllib3

urllib3.disable_warnings()

http.request('GET', 'https://example.org')

由於當我用谷歌搜索“CERTIFICATE_VERIFY_FAILED 錯誤”時這個答案仍然首先彈出,我想提供一個更新:完全關閉 SSL 驗證通常不是一個好的做法(我將在下面給出原因)。 最好將自簽名證書添加到本地受信任的證書中,而不是完全停用驗證:

import ssl
# add self_signed cert
myssl = ssl.create_default_context()
myssl.load_verify_locations('my_server_cert.pem')
# send request
response = urllib.request.urlopen("URL",context=myssl)

我們為什么要關心證書驗證?

NIST 和其他網絡安全組織推薦零信任 model 簡而言之,這意味着:僅僅因為您的服務器僅在本地網絡中,所以它不受保護。 您應該盡可能地保護 local.network 中的所有內容。

因此,如果您有一個帶有 SSL 的 web 服務器,並且客戶端未驗證安全證書,任何攻擊者仍然可以冒充此 web 服務器或通過發起中間人攻擊來竊取信息。

您已經擁有私有證書 SSL,那么為什么不在客戶端添加它並享受 SSL 的全面保護呢?

暫無
暫無

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

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