0

我曾尝试使用请求获取以下 URL,但收到 SSL 证书错误。我已经尝试了所有早期的堆栈溢出查询,但似乎没有任何工作代码:

resp = requests.get('https://www.magidglove.com/', verify=certifi.where())

我给了verify=False,还是不行

错误:

    raise MaxRetryError(_pool, url, error or ResponseError(cause))urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='www.magidglove.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))
4

2 回答 2

1

这个问题可以很容易地通过添加导入ssl到你的python代码中来解决,verify=ssl.CERT_NONE所以你的代码应该看起来像这样:

import requests
import ssl

resp = requests.get('https://www.magidglove.com/', verify=ssl.CERT_NONE)

话虽如此,在运行此代码时您可能会遇到此错误:

/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/urllib3/connectionpool.py:858:InsecureRequestWarning:正在发出未经验证的HTTPS请求。强烈建议添加证书验证。请参阅:https ://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

您可以通过在代码中添加以下行来禁用它:

import requests
import ssl
import urllib3
urllib3.disable_warnings()
resp = requests.get('https://www.magidglove.com/', verify=ssl.CERT_NONE)

希望这可以帮助!

于 2019-02-22T18:53:36.560 回答
1

TL;DR - 服务器配置错误。修复服务器,通过verify=ssl.CERT_NONE,或下载并明确通过 www.magidglove.com 的证书。

这里的问题出在服务器上,而不是客户端上。服务器仅配置为返回它自己的证书,这不足以让客户端信任它。服务器通常需要配置为返回完整的证书链。

为了诊断这一点,您可以使用openssl查看有关返回的证书链的一些原始信息:

$ openssl s_client -connect www.google.com:443 -showcerts -servername www.google.com

CONNECTED(00000003)
depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
verify return:1
depth=1 C = US, O = Google Trust Services, CN = Google Internet Authority G3
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com
verify return:1
... snipped the rest of the output ...

可以看到,服务器返回了 3 个证书,并以相反的顺序进行了验证。GlobalSign 证书受certifi图书馆信任,证书 atdepth=1是由 at 的证书创建的depth=2,最后一个证书CN=www.google.com是由 at 的证书创建的depth=1

现在让我们将其与您尝试连接的服务器进行比较:

$ openssl s_client -connect www.magidglove.com:443 -showcerts -servername www.magidglove.com

CONNECTED(00000003)
depth=0 businessCategory = Private Organization, jurisdictionC = US, jurisdictionST = Illinois, serialNumber = 00043176, C = US, ST = Illinois, L = Romeoville, O = "Magid Glove and Safety Manufacturing Company, L.L.C.", OU = web site, CN = www.magidglove.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 businessCategory = Private Organization, jurisdictionC = US, jurisdictionST = Illinois, serialNumber = 00043176, C = US, ST = Illinois, L = Romeoville, O = "Magid Glove and Safety Manufacturing Company, L.L.C.", OU = web site, CN = www.magidglove.com
verify error:num=21:unable to verify the first certificate
verify return:1

您可以从此输出中看到一些内容: - 服务器仅返回一个证书 - 客户端尝试验证证书但无法

它需要一些 ssl 知识才能知道它无法验证的原因是它不信任证书,但现在我们知道了,我们可以看到让服务器返回完整的证书链将解决这个问题。我怀疑chrome等浏览器不报错的原因是浏览器本身知道DigiCert,所以不需要全链。

于 2019-02-26T03:27:52.773 回答