SSL:CERTIFICATE_VERIFY_FAILED 在 macOS 10.15 上出现 python3 错误

SSL: CERTIFICATE_VERIFY_FAILED error with python3 on macOS 10.15

/usr/bin/python3 from Xcode/CLT on macOS 10.15(DB6/PB5 目前,Xcode 11 beta 6)对于所有 HTTPS 请求都失败并显示 SSL: CERTIFICATE_VERIFY_FAILED来自 PSL,例如来自 urllib.request:

$ /usr/bin/python3 -c 'import urllib.request; urllib.request.urlopen("https://www.apple.com/")'
...
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)>

如何解决这个问题?

(我知道答案,很快就会 post;只是分享它以防其他人 运行 加入。)

问题是 /usr/bin/python3(来自 Xcode 或 CLT)无法正确定位 /etc/ssl 中的信任库,正如我们使用 ssl.get_default_verify_paths() 看到的那样:

$ /usr/bin/python3 -c 'import ssl; print(ssl.get_default_verify_paths())'
DefaultVerifyPaths(cafile=None, capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/certs')

它正在调查 /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl,它不存在。

了解这一点,我们可以使用以下技巧:

$ sudo rsync -avzP /etc/ssl/ /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/

我已经向 Apple 提交了一份错误报告(顺便说一句,我刚刚意识到 bugreport.apple.com 现在不见了,我不得不使用反馈助手网站)。打开雷达https://openradar.appspot.com/7111585(不幸的是那个雷达号是错误的——因为bugreport.apple.com没了,我没有雷达号了,只有一个反馈号FB7111585)。

作为对@4ae1e1 回答的补充,您可以创建指向 SSL 文件夹的符号链接,而不是对其进行 rsync。这将带来额外的好处,即在 /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/ssl/.

上保持 /etc/ssl 中的任何更改是最新的
/usr/bin/sudo /bin/mkdir /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc
/usr/bin/sudo /bin/ln -s /etc/ssl/ /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.7/etc/

应该做。

python3.6 -c 'import requests; requests.get("https://www.apple.com/")'

试试这个。 检查这是否适合您。

根据 this GitHub issue,Apple 拒绝修复此问题:

The problem behaves as intended.

certifi is a third-party module, not part of Python itself.

urllib is a low-level library. It can handle SSL, but you must explicitly set up the SSL context with a cafile.

Try the following instead:

pip3 install requests
python3 -c 'import requests; print(requests.get("https://apple.com").text)'

If you only want to get cacert.pem, you can use pip3 install certifi, but you must still explicitly pass cafile to urllib.

所以我的解决方案只是简单地使用 Requests。这是受支持和未来证明。

我在更新到 catalina 后导入 'requests' 包时遇到 'abort 6' 问题。在寻找解决方案时,我被带到了这个页面。不幸的是 none 以上对我有用,但是...

从 python.org 手动更新到 python 3.8 对我来说似乎很容易解决这个问题。当我遇到错误时,我不得不重新安装我所有的包(w/pip3),但这还不错。

到目前为止,我没有看到我的任何项目与 python3.8 有问题(使用 3.7 有一段时间了)

希望这对某人有所帮助! 感谢所有额外的建议和努力!

您应该重新安装 Xcode 命令行工具,其中包含 Python。

pip3 uninstall -y -r <(pip requests certifi)
brew uninstall --ignore-dependencies python3

sudo rm -rf /Library/Developer/CommandLineTools
xcode-select --install
sudo xcode-select -r

python3 -m pip install --user certifi
python3 -m pip install --user requests