Bis*_*aul 29 python ssl openssl python-3.x
我正在尝试使用python从网络获取数据。我为此导入了urllib.request包,但是在执行时出现错误:
certificate verify failed: unable to get local issuer certificate (_ssl.c:1045)
Run Code Online (Sandbox Code Playgroud)
当我将网址更改为“ http”时-我可以获取数据。但是,我相信,这避免了检查SSL证书。
所以我检查了互联网,找到了一个解决方案:运行 /Applications/Python\ 3.7/Install\ Certificates.command
这解决了我的问题。但是我对SSL之类的东西一无所知。您能否帮助我了解它实际上解决了我的问题。
如果可能,请向我推荐任何有用的资源,以了解有关安全性和证书的信息。我是新来的。
谢谢!
注意:我确实通过链接-openssl,python请求错误:“证书验证失败”
我的问题与链接中的问题不同,因为我想知道在安装certifi软件包或运行Install\ Certificates.command该错误时实际发生了什么。我对证券知之甚少。
Ayo*_*oub 128
对于仍然想知道如何解决此问题的任何人,我通过安装“ Install Certificates.command”获得了我的
这是我的做法,
只需双击该文件等待它安装,就我而言,您就可以开始了
Ale*_*exa 61
创建从操作系统证书到 Python 的符号链接对我有用:
ln -s /etc/ssl/* /Library/Frameworks/Python.framework/Versions/3.9/etc/openssl
Run Code Online (Sandbox Code Playgroud)
(我在 macOS 上,使用pyenv)
Gal*_*tor 22
由于问题没有标签 [macos] 我在 ubuntu 下发布了同一问题的解决方案:
sudo apt install ca-certificates
sudo update-ca-certificates --fresh
export SSL_CERT_DIR=/etc/ssl/certs
Run Code Online (Sandbox Code Playgroud)
解决方案来自Github 上的Zomatree。
小智 17
这在 Mac 操作系统上对我有用:
ln -s /etc/ssl/* /Library/Frameworks/Python.framework/Versions/Current/etc/openssl/
Run Code Online (Sandbox Code Playgroud)
wan*_*ang 10
我想提供一个参考。我使用 cmd + 空格,然后键入Install Certificates.command,然后按 Enter。片刻后,弹出命令行界面开始安装。
-- removing any existing file or link
-- creating symlink to certifi certificate bundle
-- setting permissions
-- update complete
Run Code Online (Sandbox Code Playgroud)
最后,它修复了错误。
This worked in all OS:
import ssl
import certifi
urlopen(request, context=ssl.create_default_context(cafile=certifi.where()))
Run Code Online (Sandbox Code Playgroud)
Certifi提供 Mozilla\xe2\x80\x99s 精心策划的根证书集合,用于验证 SSL 证书的可信度,同时验证 TLS 主机的身份。它是从Requests项目中提取的。
pip install certifi\nRun Code Online (Sandbox Code Playgroud)\n或者运行下面的程序代码:
\n# install_certifi.py\n#\n# sample script to install or update a set of default Root Certificates\n# for the ssl module. Uses the certificates provided by the certifi package:\n# https://pypi.python.org/pypi/certifi\n\nimport os\nimport os.path\nimport ssl\nimport stat\nimport subprocess\nimport sys\n\nSTAT_0o775 = ( stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR\n | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP\n | stat.S_IROTH | stat.S_IXOTH )\n\n\ndef main():\n openssl_dir, openssl_cafile = os.path.split(\n ssl.get_default_verify_paths().openssl_cafile)\n\n print(" -- pip install --upgrade certifi")\n subprocess.check_call([sys.executable,\n "-E", "-s", "-m", "pip", "install", "--upgrade", "certifi"])\n\n import certifi\n\n # change working directory to the default SSL directory\n os.chdir(openssl_dir)\n relpath_to_certifi_cafile = os.path.relpath(certifi.where())\n print(" -- removing any existing file or link")\n try:\n os.remove(openssl_cafile)\n except FileNotFoundError:\n pass\n print(" -- creating symlink to certifi certificate bundle")\n os.symlink(relpath_to_certifi_cafile, openssl_cafile)\n print(" -- setting permissions")\n os.chmod(openssl_cafile, STAT_0o775)\n print(" -- update complete")\n\nif __name__ == \'__main__\':\n main()\nRun Code Online (Sandbox Code Playgroud)\nBrew 尚未运行适用于 Mac 的 Python3 捆绑包中的 Install Certificates.command。
\n小智 9
突然我开始在 Windows 环境中遇到这个问题。更糟糕的是,当我运行 pip 时它也出现了,所以问题不在于远程服务器证书。
在尝试了许多不同的事情之后,我找到了结合多个答案的点滴解决方案:
将可信主机添加到 pip.ini: pip config set global.trusted-host "pypi.org files.pythonhosted.org pypi.python.org" (仅作为 pip install 参数传递不起作用)
更新系统证书: pip install pip-system-certs (安装 python-certifi-win32 不起作用)
现在 https 请求又可以工作了 \o/
在我的例子中,此错误的原因是 OPENSSLDIR 设置为不包含实际证书的路径,可能是由某些升级/重新安装引起的。
要验证这一点(如果您可能遇到这种情况),请尝试运行:
openssl s_client -CApath /etc/ssl/certs/ -connect some-domain.com:443
Run Code Online (Sandbox Code Playgroud)
如果删除-CApath /etc/ssl/certs/并收到20错误代码,则这可能是原因。您还可以通过运行来检查 OPENSSSLDIR 设置的内容openssl version -a。
由于更改 OPENSSLDIR 需要重新编译,我发现最简单的解决方案是在现有路径中创建符号链接:ln -s /etc/ssl/certs your-openssldir/certs
我在OSX上遇到了同样的问题,而我的代码在Linux上完全没问题,您给出了问题的答案!
在检查了您指向的文件后/Applications/Python 3.7/Install Certificates.command,事实证明此命令将默认Python安装的根证书替换为通过certifi软件包提供的根证书。
certifi是一组根证书。每个SSL证书都依赖一个信任链:您信任一个特定的证书,因为您信任该证书的父级,也信任该父级,等等。在某些时候,没有“父级”证书,而这些证书是“根”证书。对于那些用户,除了捆绑普遍信任的根证书(通常是大型的信任公司,例如“ DigiCert”),没有其他解决方案。
例如,您可以在浏览器的安全设置中查看根证书(例如,对于Firefox->首选项->隐私和安全->查看证书->权威)。
回到最初的问题,在运行.command文件之前,执行此操作会为我返回全新安装的空白列表:
import os
import ssl
openssl_dir, openssl_cafile = os.path.split(
ssl.get_default_verify_paths().openssl_cafile)
# no content in this folder
os.listdir(openssl_dir)
# non existent file
print(os.path.exists(openssl_cafile))
Run Code Online (Sandbox Code Playgroud)
这意味着在OSX上没有Python安装的默认证书颁发机构。可能的默认值正是certifi软件包提供的默认值。
之后,您只需创建一个具有以下默认值的SSL上下文即可(certifi.where()给出证书颁发机构的位置):
import platform
# ...
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS)
ssl_context.verify_mode = ssl.CERT_REQUIRED
ssl_context.check_hostname = True
ssl_context.load_default_certs()
if platform.system().lower() == 'darwin':
import certifi
ssl_context.load_verify_locations(
cafile=os.path.relpath(certifi.where()),
capath=None,
cadata=None)
Run Code Online (Sandbox Code Playgroud)
并向urlpython 发送请求,如下所示:
import urllib
# previous context
https_handler = urllib.request.HTTPSHandler(context=ssl_context)
opener = urllib.request.build_opener(https_handler)
ret = opener.open(url, timeout=2)
Run Code Online (Sandbox Code Playgroud)
我在 Linux 上使用 conda 时遇到错误。我的解决方案很简单。
conda install -c conda-forge certifi
Run Code Online (Sandbox Code Playgroud)
我不得不使用 conda forge,因为默认的证书似乎有问题。
小智 5
对于那些仍然存在此问题的人: - MacOS 上的 Python 3.6(还有其他一些版本?)带有自己的 OpenSSL 私有副本。这意味着系统中的信任证书不再被 Python ssl 模块用作默认值。要解决这个问题,您需要在系统中安装一个certifi包。
您可以尝试通过两种方式来做到这一点:
1) 通过画中画:
pip install --upgrade certifi
Run Code Online (Sandbox Code Playgroud)
2) 如果它不起作用,请尝试运行 Python 3.6 for Mac 附带的 Cerificates.command:
open /Applications/Python\ 3.6/Install\ Certificates.command
Run Code Online (Sandbox Code Playgroud)
无论如何,您现在应该安装了证书,并且 Python 应该能够通过 HTTPS 进行连接而不会出现任何问题。
希望这有帮助。
在开头粘贴以下代码:
# paste this at the start of code
import ssl
try:
_create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
pass
else:
ssl._create_default_https_context = _create_unverified_https_context
Run Code Online (Sandbox Code Playgroud)