我正在将Python 2代码移植到Python 3的过程中,这一节讨论的是在运行Python 3中的代码时,我的本地机器发布到一个网页上( Python 2中的所有内容都很好)。我认为我的问题的根本原因是我这一方的证书没有被服务器认证。下面是我看到的错误。
Error(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1056)')))
request Error: HTTPSConnectionPool(host='my/personal.server', port=443): Max retries exceeded with url: my/personal/url/and/data (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1056)')))
错误发生在我的程序中的requests.post(url, headers)
行上。我已经确保服务器URL是正确的。
我相信问题如下。在macOS的本机Python2环境中(我以前曾经编写过代码),ssl
模块与Python3用于导入的目录中的模块不同。我的问题是:
LibreSSL
吗?cafile
ssl
模块时,如何传递和其他路径参数?FWIW,我从Python.org下载了Python3。
Python 2
⇒ python
Python 2.7.10 (default, Feb 22 2019, 21:55:15)
[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.37.14)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import ssl, sys
>>> sys.executable
'/usr/bin/python'
>>> ssl.OPENSSL_VERSION
'LibreSSL 2.2.7'
>>> ssl.get_default_verify_paths()
DefaultVerifyPaths(cafile='/private/etc/ssl/cert.pem', capath='/private/etc/ssl/certs', openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/private/etc/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/private/etc/ssl/certs')
Python 3
⇒ 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 ssl, sys
>>> sys.executable
'/usr/local/bin/python3'
>>> ssl.OPENSSL_VERSION
'OpenSSL 1.1.0j 20 Nov 2018'
>>> ssl.get_default_verify_paths()
DefaultVerifyPaths(cafile='/Library/Frameworks/Python.framework/Versions/3.7/etc/openssl/cert.pem', capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/Library/Frameworks/Python.framework/Versions/3.7/etc/openssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/Library/Frameworks/Python.framework/Versions/3.7/etc/openssl/certs')
我相信这就是为什么我有这个错误,虽然我不是100%确定。欢迎任何其他指针或输入!
编辑
按照ivan_pozdeev提出的重复问题,我能够运行openssl s_client -connect mywebsite.com:443 -verify 9
并获得Verify return code: 0 (ok)
。虽然我没有在python/bash脚本中直接调用openssl
,但我已经能够验证我的Python2配置工作。
⇒ openssl
OpenSSL> version
LibreSSL 2.6.5
OpenSSL> ca
Using configuration from /private/etc/ssl/openssl.cnf
我正在研究如何利用上面使用Python 3解释器及其库所做的事情。然而,这似乎更像是一个测试,看我是否能够与服务器对话,而不是解决参数/环境问题。
编辑2
也许这是一个调查太久的案例,但我发现了一些奇怪的东西。上面的Python2/3实例是用zsh
完成的,而不是在我的程序中完成的。当我使用这些print
语句运行我的脚本时,我会得到以下ssl
信息:
Python 2
import ssl
print ssl.OPENSSL_VERSION
print ssl.get_default_verify_paths()
输出
LibreSSL 2.2.7
DefaultVerifyPaths(cafile='/usr/local/etc/openssl/cert.pem', capath='/private/etc/ssl/certs', openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/private/etc/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/private/etc/ssl/certs')
Python 3
import ssl
print(ssl.OPENSSL_VERSION)
print(ssl.get_default_verify_paths())
输出
OpenSSL 1.1.0j 20 Nov 2018
DefaultVerifyPaths(cafile=None, capath=None, openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/Library/Frameworks/Python.framework/Versions/3.7/etc/openssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/Library/Frameworks/Python.framework/Versions/3.7/etc/openssl/certs')
Python 2脚本输出我期望的结果。Python3脚本将我的cafile
参数设置为None
,这与在None
中运行它时ssl.get_default_verify_paths()
返回的内容不同。我在我的python
脚本中使用python3
和bash
别名来调用我的bash
脚本,并且绝对确定它们引用了与python3
脚本相同的解释器。这到底是怎么回事?
发布于 2019-04-25 20:14:19
发现在环境中通过我正在包装的python的bash
shell脚本设置参数是可能的。
export SSL_CERT_FILE=/usr/local/etc/openssl/cert.pem
export REQUESTS_CA_BUNDLE=/usr/local/etc/openssl/cert.pem
我想我的脚本之前只是在看一个空的证书目录?不管怎么说,现在起作用了。我编写的路径是默认情况下OpenSSL拥有证书的位置。
发布于 2021-09-28 11:07:16
问题
我在公司防火墙后面。
我为boto3、SharePoint Online API等提供了SSL错误(代码片段):
SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1129)')))
通过我的网络管理(即IT安全),我发现我们的Netskope工具使用了自己的代理证书。
最简单的解决方案
我发现了一些可能的解决方案,包括杜克的bash包装器,将证书复制到给定的文件夹中,或者请求的“verify=”路径。但是我想要一个简单的解决方案,它不需要移动任何系统文件,也不需要新的依赖项,而且很容易随着以后Docker容器的使用而扩展。我发现您可以设置这样的会话环境:
import os
os.environ["REQUESTS_CA_BUNDLE"] = 'C:/ProgramData/Netskope/STAgent/download/nscacert.pem'
os.environ["SSL_CERT_FILE"] = 'C:/ProgramData/Netskope/STAgent/download/nscacert.pem'
https://stackoverflow.com/questions/55736855
复制相似问题