首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何更改Python3中ssl模块中的“cafile”参数?

如何更改Python3中ssl模块中的“cafile”参数?
EN

Stack Overflow用户
提问于 2019-04-17 22:35:11
回答 2查看 6.3K关注 0票数 2

我正在将Python 2代码移植到Python 3的过程中,这一节讨论的是在运行Python 3中的代码时,我的本地机器发布到一个网页上( Python 2中的所有内容都很好)。我认为我的问题的根本原因是我这一方的证书没有被服务器认证。下面是我看到的错误。

代码语言:javascript
运行
复制
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用于导入的目录中的模块不同。我的问题是:

  • 可以在Python3实例中使用LibreSSL吗?
  • 如果不是,当我在Python3中导入cafile ssl 模块时,如何传递和其他路径参数?

FWIW,我从Python.org下载了Python3。

Python 2

代码语言:javascript
运行
复制
⇒  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

代码语言:javascript
运行
复制
⇒  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配置工作。

代码语言:javascript
运行
复制
⇒  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

代码语言:javascript
运行
复制
import ssl
print ssl.OPENSSL_VERSION
print ssl.get_default_verify_paths()

输出

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
import ssl
print(ssl.OPENSSL_VERSION)
print(ssl.get_default_verify_paths())

输出

代码语言:javascript
运行
复制
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脚本中使用python3bash别名来调用我的bash脚本,并且绝对确定它们引用了与python3脚本相同的解释器。这到底是怎么回事?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-25 20:14:19

发现在环境中通过我正在包装的python的bash shell脚本设置参数是可能的。

代码语言:javascript
运行
复制
export SSL_CERT_FILE=/usr/local/etc/openssl/cert.pem
export REQUESTS_CA_BUNDLE=/usr/local/etc/openssl/cert.pem

我想我的脚本之前只是在看一个空的证书目录?不管怎么说,现在起作用了。我编写的路径是默认情况下OpenSSL拥有证书的位置。

票数 4
EN

Stack Overflow用户

发布于 2021-09-28 11:07:16

问题

我在公司防火墙后面。

我为boto3、SharePoint Online API等提供了SSL错误(代码片段):

代码语言:javascript
运行
复制
SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1129)')))

通过我的网络管理(即IT安全),我发现我们的Netskope工具使用了自己的代理证书。

最简单的解决方案

我发现了一些可能的解决方案,包括杜克的bash包装器,将证书复制到给定的文件夹中,或者请求的“verify=”路径。但是我想要一个简单的解决方案,它不需要移动任何系统文件,也不需要新的依赖项,而且很容易随着以后Docker容器的使用而扩展。我发现您可以设置这样的会话环境:

代码语言:javascript
运行
复制
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'
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55736855

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档