繁体   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