请求模块抛出 OpenSSL.SSL.Error [英] Requests module throwing OpenSSL.SSL.Error

查看:57
本文介绍了请求模块抛出 OpenSSL.SSL.Error的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用来自 euronext.com 的 REST API,为了更进一步,我需要验证服务器证书并通过模块请求发送我自己的客户端证书.

I'm using a REST API from euronext.com, to go any further I need to verify the server certificate and send my own client certificate through the module requests.

我已经用 curl 做了一些测试,.crt/.pem 文件都被接受了.

I already did some testing with curl, both .crt/.pem files were accepted.

但是请求仍在抛出:

DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): saturn-api-h.euronext.com
Traceback (most recent call last):
  File "C:\python36\lib\site-packages\urllib3\contrib\pyopenssl.py", line 441, in wrap_socket
cnx.do_handshake()
  File "C:\python36\lib\site-packages\OpenSSL\SSL.py", line 1806, in do_handshake
self._raise_ssl_error(self._ssl, result)
  File "C:\python36\lib\site-packages\OpenSSL\SSL.py", line 1546, in _raise_ssl_error
_raise_current_error()
  File "C:\python36\lib\site-packages\OpenSSL\_util.py", line 54, in exception_from_error_queue
raise exception_type(errors)
OpenSSL.SSL.Error: [('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')]

我为解决问题所做的尝试:

What I did try to solve the issue :

  • 遵循请求文档
  • 将请求模块更新到 2.18.4
  • 安装 pyOpenSSL 17.5.0
  • 检查 .crt/.pem 格式
  • 卷曲测试

工作卷曲:

curl -i -vvv -X POST https://saturn-api-h.euronext.com/SaturnWebServices/rest/Authentication/AuthenticateUser -H "Content-Type: application/json" --cert ./client.crt --cacert ./digicert-full-chain.crt

如果有一个有效的 Authorization 标头,它会返回一个 200 状态码,没有它会返回 401拒绝访问!".如果证书验证失败,它会重定向到 euronext.com,状态码为 302.

With a valid Authorization headers it return a 200 status code, without it 401 "Access denied!". If the certificate validation fails, it redirects to euronext.com with status code 302.

有问题的蟒蛇:

endpoint = 'https://saturn-api-h.euronext.com/SaturnWebServices/rest/Authentication/AuthenticateUser'       
headers = { 'Content-Type': 'application/json', } #'Authorization': 'Basic <auth_string>',

r = requests.post(endpoint, headers = headers, verify = './digicert-full-chain.crt', cert = './client.crt')

证书:

  • digicert-full-chain.crt 包含来自 DigiCert 的完整链:

  • digicert-full-chain.crt is containing the full chain from DigiCert:

  • DigiCertAssuredIDRootCA.pem
  • DigiCertSHA2AssuredIDCA.pem
  • DigiCertSHA2SecureServerCA.pem

client.crt 包含我们的证书及其密钥.

client.crt is containg our certificate and its key.

为什么 curl 命令有效,而 python 的 requests 模块却失败了?

Why is curl command working whereas python's requests module is failling?

有没有办法从请求模块中显示完整的握手过程?

Is there any way to show the complete handshake process from the requests module?

推荐答案

我自己解决了这个问题,整个链中缺少一个证书.

I solved the problem myself, a certificate was missing from the full chain.

/usr/local/lib/python3.4/dist-packages/certifi/cacert.pem >certifi-digicert.pem;digicert-full-chain.pem >>certifi-digicert.pem 并将生成的证书传递给 verify 参数起作用.

Doing /usr/local/lib/python3.4/dist-packages/certifi/cacert.pem > certifi-digicert.pem; digicert-full-chain.pem >> certifi-digicert.pem and passing the resulting certificate to the verify argument worked.

作为旁注,我使用了 strace 命令来比较 python 和 curl 的证书位置:

As a side note, I used the strace command to compare certificate locations from both python and curl:

  • strace |&grep 打开 |grep -E 'crt|pem'
  • strace |&grep 打开 |grep -E 'crt|pem'

我还检查了 Wireshark 以获得完整的握手过程,pyOpenSSL 模块在服务器的证书请求后收到错误.警报(级别:致命,描述:未知 CA).

I also checked with Wireshark to get the full handshake process, the pyOpenSSL module was getting an error after the server's Certificate Request. Alert (Level: Fatal, Description: Unknown CA).

这篇关于请求模块抛出 OpenSSL.SSL.Error的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆