当 ssl 设置看起来正常时,为什么我在 Python 中得到 [SSL: CERTIFICATE_VERIFY_FAILED]?

2024-01-19

我正在开发一个 Python 应用程序,通过安全的 websocket 协议与本地主机上运行的服务进行通信。 这是示例代码:

import json
import asyncio
import websockets
import ssl
import certifi


ssl_context = ssl.create_default_context()
ssl_context.load_verify_locations(certifi.where())
ssl_context.load_default_certs()

query =  {
    "jsonrpc": "2.0",
    "method": "queryHeadsets",
    "params": {},
    "id": 1
    }
json = json.dumps(query)

async def query(json):

    async with websockets.connect("wss://emotivcortex.com:54321") as ws:
        await ws.send(json)
        response = await ws.recv()
        print(response)

asyncio.get_event_loop().run_until_complete(query(json))

问题是 ssl 握手不断失败,并出现以下错误:

ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)

我运行的是 Windows 10、Python 3.7.3 64 位

$pip list
Package    Version
---------- --------
certifi    2019.3.9
pip        19.0.3
setuptools 40.8.0
websockets 7.0

我已检查了该服务提供的证书。它似乎有效并由 COMODO 签署。 我试过了:

ssl_context = ssl.create_default_context()
ssl_context.load_verify_locations(certifi.where())
print(ssl.get_default_verify_paths())
print(ssl_context.cert_store_stats())
ssl_context.load_default_certs()
print(ssl_context.get_ca_certs())

发现有几个可用于 python 的 COMODO CA 证书。但我仍然收到错误。

如果有帮助的话,这是完整的错误消息:

SSL handshake failed on verifying the certificate
protocol: <asyncio.sslproto.SSLProtocol object at 0x0000020C11283048>
transport: <_SelectorSocketTransport fd=508 read=polling write=<idle, bufsize=0>>
Traceback (most recent call last):
  File "C:\Users\Matyas2\Python\lib\asyncio\sslproto.py", line 625, in _on_handshake_complete
    raise handshake_exc
  File "C:\Users\Matyas2\Python\lib\asyncio\sslproto.py", line 189, in feed_ssldata
    self._sslobj.do_handshake()
  File "C:\Users\Matyas2\Python\lib\ssl.py", line 763, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)
SSL error in data received
protocol: <asyncio.sslproto.SSLProtocol object at 0x0000020C11283048>
transport: <_SelectorSocketTransport closing fd=508 read=idle write=<idle, bufsize=0>>
Traceback (most recent call last):
  File "C:\Users\Matyas2\Python\lib\asyncio\sslproto.py", line 526, in data_received
    ssldata, appdata = self._sslpipe.feed_ssldata(data)
  File "C:\Users\Matyas2\Python\lib\asyncio\sslproto.py", line 189, in feed_ssldata
    self._sslobj.do_handshake()
  File "C:\Users\Matyas2\Python\lib\ssl.py", line 763, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)
Traceback (most recent call last):
  File "test.py", line 37, in <module>
    asyncio.get_event_loop().run_until_complete(query(json))
  File "C:\Users\Matyas2\Python\lib\asyncio\base_events.py", line 584, in run_until_complete
    return future.result()
  File "test.py", line 32, in query
    async with websockets.connect("wss://emotivcortex.com:54321") as ws:
  File "C:\Users\Matyas2\Python\lib\site-packages\websockets\py35\client.py", line 2, in __aenter__
    return await self
  File "C:\Users\Matyas2\Python\lib\site-packages\websockets\py35\client.py", line 12, in __await_impl__
    transport, protocol = await self._creating_connection
  File "C:\Users\Matyas2\Python\lib\asyncio\base_events.py", line 986, in create_connection
    ssl_handshake_timeout=ssl_handshake_timeout)
  File "C:\Users\Matyas2\Python\lib\asyncio\base_events.py", line 1014, in _create_connection_transport
    await waiter
  File "C:\Users\Matyas2\Python\lib\asyncio\sslproto.py", line 526, in data_received
    ssldata, appdata = self._sslpipe.feed_ssldata(data)
  File "C:\Users\Matyas2\Python\lib\asyncio\sslproto.py", line 189, in feed_ssldata
    self._sslobj.do_handshake()
  File "C:\Users\Matyas2\Python\lib\ssl.py", line 763, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)

与 Internet 中服务器的 SSL 连接工作正常。 我缺少什么? 我究竟做错了什么?

如果需要,我很乐意提供更多信息。

EDIT:该证书适用于 emotivcortex.com,由 COMODO RSA 域验证安全服务器 CA 颁发,因此我认为它不是自签名证书。 OpenSSL:

$python -c "import ssl; print(ssl.OPENSSL_VERSION)"
OpenSSL 1.1.0j  20 Nov 2018

该问题是由缺少中间 CA 证书引起的。

通过检查 OpenSSL 中的服务提供的证书,我发现该证书是由“COMODO RSA 域验证安全服务器 CA”颁发的。这个特定机构的CA证书实际上是not存在于 python 包的 CA 包中certifi(有不同的COMODO...证书)。

Solution

从 CA 网页手动下载 PEM 格式的缺失证书,并将其添加到代码中使用的 CA 捆绑包中。

另外,应用程序代码中存在错误: 调用函数时websockets.connect(),传递关键字参数ssl=ssl_context因此实际上使用了之前指定的 CA 捆绑包。 正确的代码如下所示:

import json
import asyncio
import websockets
import ssl
import certifi


ssl_context = ssl.create_default_context()
ssl_context.load_verify_locations(certifi.where())


query =  {
    "jsonrpc": "2.0",
    "method": "queryHeadsets",
    "params": {},
    "id": 1
    }
json = json.dumps(query)

async def query(json):
    
    async with websockets.connect("wss://emotivcortex.com:54321", ssl=ssl_context) as ws:
        await ws.send(json)
        response = await ws.recv()
        print(response)

asyncio.get_event_loop().run_until_complete(query(json))

非常感谢larsks and 史蒂芬·乌尔里希为我指明了正确的方向。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当 ssl 设置看起来正常时,为什么我在 Python 中得到 [SSL: CERTIFICATE_VERIFY_FAILED]? 的相关文章

  • 将 ical 附件的邮件消息的内容类型设置为“text/calendar; method=REQUEST”

    我正在尝试使用 App Engine 邮件 API 从 App Engine 发送 iCalendar 格式的 ics 文件 这在 GMail 中非常有效 但是 Outlook 无法识别该文件 我认为问题在于内容类型设置为 文本 日历 而不
  • 如何并排绘制具有相同 X 坐标的条形图(“闪避”)

    import matplotlib pyplot as plt gridnumber range 1 4 b1 plt bar gridnumber 0 2 0 3 0 1 width 0 4 label Bar 1 align cente
  • 在二维数组中进行所有可能的组合

    我正在尝试制作具有所有可能组合的 4x4 16 像素黑白图像数组 我制作了以下数组作为模板 template 0 0 0 0 start with all white pixels 0 0 0 0 0 0 0 0 0 0 0 0 然后我想迭
  • 学习Python中的解析器

    我记得我读过有关解析器的内容 您只需提供一些示例行 它就知道如何解析某些文本 它只是确定两条线之间的差异 以了解可变部分是什么 我以为它是用 python 写的 但我不确定 有谁知道那是什么图书馆吗 可能你的意思是模板制作器 http co
  • virtualenvwrapper 函数在 shell 脚本中不可用

    所以 我再一次制作了一个很棒的 python 程序 它让我的生活变得更加轻松 并节省了大量时间 当然 这涉及到一个 virtualenv 用mkvirtualenvvirtualenvwrapper 的功能 该项目有一个requiremen
  • 有什么好的适用于 Google App Engine 应用程序的 AJAX 框架吗? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在尝试在我的 Google App Engine 应用程序中实现 AJAX 因此我正在寻找一个好的
  • 使用ideone时如何传入命令行参数?

    我正在使用 ideone 在线解释器 http ideone com http ideone com 来测试一些 C 和 Python 程序 如何指定命令行参数而不是使用 STDIN 输入 看起来你不能 但是快速破解应该做的伎俩 stati
  • 是否可以在 IPython 控制台中显示 pandas 样式?

    是否可以显示熊猫风格 https pandas pydata org pandas docs stable user guide style html在 iPython 控制台中 Jupyter 笔记本中的以下代码 import panda
  • pandas read_csv 之前预处理数据文件

    我使用 SAP 的数据输出 但它既不是 CSV 因为它不引用包含其分隔符的字符串 也不是固定宽度 因为它具有多字节字符 它是一种 固定宽度 字符 为了将其放入 pandas 我当前读取文件 获取分隔符位置 对分隔符周围的每一行进行切片 然后
  • 在多核上运行 python 线程

    我知道Python 2 7不允许在不同的内核上运行多个线程 你需要使用multiprocessing模块以实现某种程度的并发性 我正在看concurrent futuresPython 3 4 中的模块 是否使用ThreadPoolExec
  • 将列表值转换为 pandas 中的行

    我有数据帧 其中一列具有相同长度的 numpy ndarray 值 df list 0 Out 92 array 0 0 0 0 29273096 0 30691767 0 27531403 我想将这些列表值转换为数据框并从 df iloc
  • matplotlib:渲染到缓冲区/访问像素数据

    我想使用 matplotlib 生成的图作为 OpenGL 中的纹理 到目前为止 我遇到的 matplotlib 的 OpenGL 后端要么不成熟 要么已经停止使用 所以我想避免使用它们 我当前的方法是将图形保存到临时 png 文件中 并从
  • 如何在Python中手动对数字列表进行排序?

    规格 Ubuntu 13 04 Python 3 3 1 背景 Python的初学者 遇到了这个 手动排序 问题 我被要求做的事情 让用户输入 3 个数值并将它们存储在 3 个不同的变量中 不使用列表或排序算法 手动将这 3 个数字从小到大
  • 尝试校准keras模型

    我正在尝试通过 Sklearn 实现来校准我的 CNN 模型CalibratedClassifierCV 尝试将其包装为KerasClassifier并覆盖预测功能但没有成功 有人可以说我做错了什么吗 这是模型代码 def create m
  • 如何在 python 中使用交叉验证执行 GridSearchCV

    我正在执行超参数调整RandomForest如下使用GridSearchCV X np array df features all features y np array df gold standard labels x train x
  • matplotlib vlines 图中未应用 y 轴的最小值

    我正在 matplotlib 中绘制 vlines 图 数据集中的所有 y 值如下 gt 0 我希望 y 轴最底部的刻度能够读取0 但相反 我得到 500 这是代码 usr bin env python import numpy as np
  • Pygame:有人可以帮我实现双跳吗?

    我知道已经有其他关于此问题的帖子了 但我的运动系统与我发现的有点不同 所以随后我问这个问题 我的运动系统基于一个名为的命名元组Move up left right down 然后就是这个 def update self move block
  • 在字符串内打印单引号

    我想输出 XYZ s ABC 我在Python IDLE中尝试了以下3条语句 第一条和第二条语句输出 a before 带打印功能的第三条语句不输出 before 作为 Python 新手 我想了解为什么 之前输出 在第 1 条和第 2 条
  • 在Python中随机交错2个数组

    假设我有两个数组 a 1 2 3 4 b 5 6 7 8 9 我想将这两个数组交错为变量 c 注意 a 和 b 不一定具有相同的长度 但我不希望它们以确定性的方式交错 简而言之 仅仅压缩这两个数组是不够的 我不想要 c 1 5 2 6 3
  • 如何使 Django 自定义管理命令参数不再需要?

    我正在尝试在 django 中编写自定义管理命令 如下所示 class Command BaseCommand def add arguments self parser parser add argument delay type int

随机推荐