如何让 Python 使用来自 Mac OS TrustStore 的 CA 证书?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40684543/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 23:48:48  来源:igfitidea点击:

How to make Python use CA certificates from Mac OS TrustStore?

pythonmacosssltruststore

提问by sorin

I need to use curtom root certificates on the company intranet and loading them in the Mac OS TrustStore (KeyChain) does solve the problem for all browsers and GUI apps.

我需要在公司 Intranet 上使用 curtom 根证书并将它们加载到 Mac OS TrustStore (KeyChain) 中确实解决了所有浏览器和 GUI 应用程序的问题。

It seems that it works even with the version of curlthat ships with Mac OS X but it doesn't work with python, even the version that ships with Mac OS 10.12 Sierra (Python 2.7.10)

似乎它甚至适用curl于 Mac OS X 附带的版本,但它不适用于 python,即使是 Mac OS 10.12 Sierra (Python 2.7.10) 附带的版本

Still, it seems that I would be hit by:

不过,似乎我会受到以下打击:

urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)>

How can I solve this?

我该如何解决这个问题?

Because I encounter this issue in lots and lots of Python tools I would really appreciate if I find a way to avoid it without having to patch them.

因为我在很多 Python 工具中都遇到过这个问题,如果我能找到一种方法来避免它而无需修补它们,我会非常感激。

Providing the custom CA certificate myself is not an option because I cannot patch tens of Python tools that I use.

自己提供自定义 CA 证书不是一种选择,因为我无法修补我使用的数十种 Python 工具。

Most of the tools are using the requestslibrary but there are a few that are using the native ssl support in Python directly.

大多数工具都在使用该requests库,但也有一些工具直接使用Python 中的原生 ssl 支持。

采纳答案by sorin

If you put the additional certificates in a PEM bundle file you can use these two environment variables to overwrite the default cert stores used by Python openssl and requests.

如果将附加证书放在 PEM 包文件中,则可以使用这两个环境变量覆盖 Python openssl 和 requests 使用的默认证书存储。

SSL_CERT_FILE=/System/Library/OpenSSL/cert.pem
REQUESTS_CA_BUNDLE=/System/Library/OpenSSL/cert.pem

Please note that this file does not exist, you need to build it yourself.

请注意,此文件不存在,您需要自己构建。

回答by j7nn7k

This is also a problem in Python 3.6 with MacOS Sierrra. I know your use case is different. But I stumbled upon this thread while investigating this problem. So if anyone is also having this article is worth checking out:

这也是 MacOS Sierrra 的 Python 3.6 中的一个问题。我知道你的用例是不同的。但是我在调​​查这个问题时偶然发现了这个线程。因此,如果有人也有这篇文章值得一看:

http://www.cdotson.com/2017/01/sslerror-with-python-3-6-x-on-macos-sierra/

http://www.cdotson.com/2017/01/sslerror-with-python-3-6-x-on-macos-sierra/

In a nutshell: Python 3.6 does not rely on MacOS' openSSL anymore. It comes with its own openSSL bundled and doesn't have access on MacOS' root certificates.

简而言之:Python 3.6 不再依赖 MacOS 的 openSSL。它捆绑了自己的 openSSL,并且无法访问 MacOS 的根证书。

You have two options:

您有两个选择:

Run an install command shipped with Python 3.6

运行 Python 3.6 附带的安装命令

cd /Applications/Python\ 3.6/
./Install\ Certificates.command

or

或者

Install the certifi packagewith

安装CERTIFI包

pip install certifi

I chose the first option and it worked.

我选择了第一个选项,它奏效了。

回答by Hitesh Patel

Run this to set the appropriate variables. This is a combination of the answers that have already been given here. Put it in your ~/.bash_profile to make it permanent.

运行它以设置适当的变量。这是这里已经给出的答案的组合。把它放在你的 ~/.bash_profile 中以使其永久化。

CERT_PATH=$(python -m certifi)
export SSL_CERT_FILE=${CERT_PATH}
export REQUESTS_CA_BUNDLE=${CERT_PATH}

回答by JS.

As an update and datapoint, I ran into this issue running Python 3.7.0 on macOS 10.13.4:

作为更新和数据点,我在 macOS 10.13.4 上运行 Python 3.7.0 时遇到了这个问题:

$ ipython
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 26 2018, 23:26:24)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.0.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import bokeh.sampledata

In [2]: bokeh.sampledata.download()
Using data directory: /Users/me/.bokeh/data

...
SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1045)

Instructions for solving the problem are in /Applications/Python\ 3.7/ReadMe.rtf

解决问题的说明在 /Applications/Python\ 3.7/ReadMe.rtf

Following the suggestion there and running /Applications/Python\ 3.7/Install\ Certificates.commandsolved the problem:

按照那里的建议并运行/Applications/Python\ 3.7/Install\ Certificates.command解决了问题:

From the terminal:

从终端:

$ /Applications/Python\ 3.7/Install\ Certificates.command

Re-starting IPython...

重新启动 IPython...

$ ipython
>>> import bokeh.sampledata

>>> bokeh.sampledata.download()
Using data directory: /Users/me/.bokeh/data
Downloading: CGM.csv (1589982 bytes)
   1589982 [100.00%]
...

回答by luckrill

Mac brew install python env.

Mac brew 安装 python 环境。

$ python3
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 16:52:21) 
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import certifi
>>> certifi.where()
'/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/certifi/cacert.pem'
>>> 

Or from the command line:

或者从命令行:

$ python -m certifi

then need link cacert.pem as cert.pem

然后需要将 cacert.pem 链接为 cert.pem

$ ln -s /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/certifi/cacert.pem cert.pem
$ pwd
/Library/Frameworks/Python.framework/Versions/3.7/etc/openssl

rehash

then work fine.

然后工作正常。

回答by Rocko

For me /Applications/Python\ 3.6/./Install\ Certificatescommand fails on pip certifi install. I am on mac High Sierra and use python3 so pip somewhat fails and I have to use pip3 instead.

对我来说/Applications/Python\ 3.6/./Install\ Certificates,pip certifi 安装命令失败。我在 mac High Sierra 上使用 python3,所以 pip 有点失败,我必须改用 pip3。

So here what I did:

所以在这里我做了什么:

  1. Manually ran pip3 install --update certifyin a shell
  2. Remove the install certifi line from the command script
  3. Reran the script and everything was fine.
  1. pip3 install --update certify在 shell 中手动运行
  2. 从命令脚本中删除安装证书行
  3. 重新运行脚本,一切都很好。

Note that you will end up with a cert.pem symbolic link in: /Library/Frameworks/Python.framework/Versions/3.6/etc/openssl/

请注意,您最终将在以下位置获得 cert.pem 符号链接: /Library/Frameworks/Python.framework/Versions/3.6/etc/openssl/