我正在尝试在以“https”开头的网站上使用 urllib.request.urlopen。错误输出是:
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败
有很多很棒的线程可以解决这个错误。包括this one其中提到了 SSL Labs 评级。我能够在我测试过的所有其他“https”站点上使用 urllib.request.urlopen。
SSL 实验室显示以下输出:
Key RSA 2048 bits (e 65537)
Issuer Let's Encrypt Authority X3
AIA: http://cert.int-x3.letsencrypt.org/
Signature algorithm SHA256withRSA
Extended Validation No
Certificate Transparency No
OCSP Must Staple No
Revocation information OCSP
Revocation status Good (not revoked)
DNS CAA No (more info)
Trusted Yes
澄清一下,我的问题是:是否有完成握手的解决方案,其中不包括绕过证书验证?如果有解决方案,是否可以在 linux、macOS 和 Windows 上完全在 python 脚本中解决?
最佳答案
我无法为 urllib 回答这个问题,但我可以使用 python 请求来解决这个问题。请注意,这仅在相关网站存在受信任的证书链但服务器可能缺少根证书或中间证书时才有效。
使用 SSL 实验室服务器测试 (linked here) ,运行测试并向下滚动到认证路径。如果确实存在受信任的证书路径,但服务器出于某种原因未提供完整的链,您可以在此处下载完整的受信任路径作为文本。复制完整的证书链并将其保存为 .pem 文件并将此文件的路径传递给请求函数:
r = requests.get(url, verify = "path/to/chain.pem")
requests 模块会抛出各种与 SSL 相关的认证失败,其中许多是服务器端问题,您确实希望避免禁用 SSL 验证。此解决方案仅适用于存在完整证书但问题的颁发者或服务器草率地省略了根证书或中间证书的罕见情况。
关于python - 如果 SSL Labs 显示 "This server' 的证书链不完整,证书握手能否完成。等级上限为B。”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45344605/