首页 > 解决方案 > 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 上。

为什么会这样?有任何想法吗?

标签: pythonsslopenssl

解决方案


我在阅读这篇文章和关于 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 连接也正常工作。


推荐阅读