带有自签名证书的Python 3 urllib

mv1qrgav  于 2023-01-27  发布在  Python
关注(0)|答案(4)|浏览(179)

我尝试使用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)>

在阅读网页时,很明显Python 2.6的urllib2并不麻烦验证证书,一些版本的urllib允许“verify=False”被传递给方法签名,但是这在Python 3.4中似乎不起作用。
有人知道我该如何解决这个问题吗?由于公司安全准则,我希望避免使用Requests包。

kh212irz

kh212irz1#

使用以下命令禁用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");
bqucvtff

bqucvtff2#

urllib.request.urlopen具有接受SSLContext对象的上下文关键字参数。因此,传递.verify_mode设置为ssl.CERT_NONE的SSLContext对象,即SSLContext.verify_mode = ssl.CERT_NONE应等于verify=False

u3r8eeie

u3r8eeie3#

使用urllib3时:

import urllib3

urllib3.disable_warnings()

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

ma8fv8wu4#

当我在谷歌上搜索“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和其他网络安全组织推荐零信任模式。简言之,这意味着:正因为你的服务器只在本地网络中,所以它不受保护。2你应该尽最小的努力来保护本地网络中的所有东西。
因此,如果您有一个使用SSL的Web服务器,并且安全证书未经客户端验证,任何攻击者仍然可以模拟此Web服务器或通过发起中间人攻击来窃取信息。
您已经有了私有SSL证书,那么为什么不将其添加到客户端并享受SSL的全面保护呢?

相关问题