【问题标题】:SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败:无法获取本地颁发者证书 (_ssl.c:1123)
【发布时间】:2021-08-03 10:42:09
【问题描述】:

我正在尝试使用requests 创建一个 Python (3.9.2) 客户端,以通过 SSL 与使用 socket.io 的 node.js (12.13.0) 服务器通信。

仅当我将 verify = False 放在 Python 客户端时,它才对我有效。如果没有verify = False,我会遇到不同的错误,具体取决于设置。在我看来最有效的东西会从标题中抛出错误。

该设置是(简化的)-

服务器节点.JS:

const express = require('express')
const fs = require('fs')
const socketIo = require("socket.io")
const app = express()

var cert = "path\to\cert.pfx"
if (fs.existsSync(cert)) {
    httpsServer = require('https').createServer({
        pfx: fs.readFileSync(cert),
        passphrase: 'reall_pass_here',
        requestCert: true,
        rejectUnauthorized: false //shoud be true on production
    }, app)
}


httpsServer.listen(port, function () {
    console.log('[Info]', 'httpsServer is running on port', port);
        });
        
app.post('/', async (req, res) => {
    console.log(req.headers)
    console.log(req.body)
    //do nice things here
    res.sendStatus(200)
})

客户端 Python:

import requests

response = requests.post("https://myserver.com:12457/"
    # , verify = False
    , headers={"Content-Type": "application/json"}
    , data=json.dumps({"base64Image": encoded_string, "imageName": imageName}))
print("SendPhoto", response.status_code)

当使用在线 API 测试服务(如 https://reqbin.com/)时,它会按预期工作,所以我认为问题出在客户端。

看这里:https://stackoverflow.com/a/66111417/627100 和类似的帖子,我可以理解问题很常见,但提供的解决方案对我来说并不清楚。由于我可以访问服务器和客户端,因此我从原始 GoDaddy 文件中获取了 PEM 证书,并将其粘贴到客户端 venv 上的 certifi PEM 文件中。它没有解决问题。我当然不确定这种行为是否有效或安全。我还想从浏览器的挂锁中导出证书,但它不提供 PEM 格式。 我知道服务器必须提供完整的证书链,包括中间证书。也许它没有(那么在线 API 测试器是如何工作的?) - 我怎样才能做到?还是让客户无视需求?还是手动“带来”? (不适用于生产...) 我想我需要在这里做一个详细的解释......

【问题讨论】:

  • 问题出在所提供的证书(如中间缺失)或您信任的证书上。这一切实际上都不为人所知,即只有一些陈述描述了您认为的情况,但没有显示事实实际情况。如果没有这些信息,则无法提供详细的帮助。 “我从原始 GoDaddy 文件中获取了 PEM 证书并将其粘贴到 certifi PEM 文件中......” - 尝试将服务器证书添加为受信任的 CA 将无济于事,因为服务器证书不是一个 CA。
  • 感谢@SteffenUllrich,我将“撤消” PEM,因为现在我很清楚它不是受信任的 CA

标签: python node.js ssl request


【解决方案1】:

通常“无法获取本地颁发者证书”错误清楚地表明,如果您的客户端在 Windows 计算机上运行,​​则颁发者(在您的情况下为 GoDaddy)根证书未安装在系统的受信任的根证书颁发机构存储中。或者在 Linux 机器的情况下,'/etc/ssl/certs/ca-certificates.crt' 中缺少它。

您可以从here 下载 GoDaddy 的根证书。

【讨论】:

  • 感谢鲁斯塔姆。因此,受信任的根 CA 是每个权限一个,并且服务器应该将其提供给客户端?您是否建议我需要在 Windows 服务器上验证(并安装)它?顺便说一句,当我通过此测试仪测试证书时:digicert.com/help,它全部为绿色,包括“Subject Go Daddy Root Certificate Authority - G2 Valid from 01/Jan/2014 to 30/May/2031 Issuer”。跨度>
  • 是的,当您通过 SSL 连接到服务器并将证书发回时,您的客户端会检查内部指定的证书颁发机构。因此,您需要确保 GoDaadies 根证书已安装在客户端的 CA 根存储中。
猜你喜欢
  • 2021-07-20
  • 1970-01-01
  • 2021-11-25
  • 2020-12-13
  • 1970-01-01
  • 2020-04-12
  • 2020-04-06
  • 2020-03-04
  • 1970-01-01
相关资源
最近更新 更多