python - SSL:在 Python 3.8 上运行时的 CERTIFICATE_VERIFY_FAILED。适用于其他版本的python
问题描述
我在 macos 上使用 Python 3.8。我在这台机器上也有 Python 3.5 和 2.7。
我正在尝试使用以下代码段连接到 adwords.google.com:
import ssl, socket
context = ssl.create_default_context()
conn = context.wrap_socket(
socket.socket(socket.AF_INET),
server_hostname="adwords.google.com"
)
conn.connect(("adwords.google.com", 443))
cert = conn.getpeercert()
但我总是收到以下错误:
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate
运行 ssl.OPENSSL_VERSION 我收到:
'OpenSSL 1.1.1g 21 Apr 2020'
奇怪的是,如果我在 Python 3.5 或 Python 2.7 上运行相同的 ssl 连接片段,则连接有效。这只发生在 Python 3.8 上。
为什么会这样?有任何想法吗?
解决方案
我在阅读这篇文章和关于 SO 的这个问题时找到了答案: Django 1.11: Python 3.6 Upgrade cause issues with SSL connections。
从 Python 3.6 开始,[...] 已弃用的 Apple 提供的 OpenSSL 库不再使用。这也意味着由 Keychain Access 应用程序和安全命令行实用程序管理的系统和用户钥匙串中的信任证书不再被 Python ssl 模块用作默认值。对于 3.6.0,/Applications/Python 3.6 中包含一个示例命令脚本,用于安装来自第三方 certifi 包 ( https://pypi.python.org/pypi/certifi ) 的默认根证书的精选包。 ..]
所以,我只运行了 sh /Applications/Python\ 3.8/Install\ Certificates.command,certifi 已正确安装,并且 ssl 连接也正常工作。
推荐阅读
- woocommerce - 在视口上的大型菜单中延迟加载图像
- python - Numpy - 在多个轴上设置第一个最大值
- html - 我怎样才能使淡出文本
- c++ - 我正在尝试使用数组添加大量数字而不使用 bigint 或类似的东西。C++
- linux - Bash 管道执行顺序
- r - Custom function: allow unknown number of groups for operations
- coq - 在coq中定义一个多态类型
- javascript - 如何在加载页面上破坏用户会话并强制用户注销?
- html - 哪个 R 包可以解析 HTML 字符串来告诉我文本中的哪些单词是粗体、斜体等?
- python - 日期时间 - 确定 10 秒是否已过