python-3.x - 在应用程序中为 discord.py 安装 ssl 证书

标签 python-3.x macos ssl discord.py

我正在制作一个基于 python 的 mac 应用程序,它使用 discord.py做不和谐的事情。根据我之前制作不和谐机器人的经验,运行不和谐机器人需要您运行 Install Certificates.command在你的python版本中。但是,如果其他用户使用此应用程序,我不想要求他们安装 python。我从 Install Certificates.command 中获取了一段代码,认为它会将证书放在用户计算机上的正确位置。但是,测试人员在他们的计算机上运行应用程序时遇到此错误:

Traceback (most recent call last):
  File "Interface.py", line 136, in <module>
  File "installCerts.py", line 25, in installCerts
FileNotFoundError: [Errno 2] No such file or directory: '/Library/Frameworks/Python.framework/Versions/3.8/etc/openssl'
[2514] Failed to execute script 'Interface' due to unhandled exception: [Errno 2] No such file or directory: '/Library/Frameworks/Python.framework/Versions/3.8/etc/openssl'
[2514] Traceback:
Traceback (most recent call last):
  File "Interface.py", line 136, in <module>
  File "installCerts.py", line 25, in installCerts
FileNotFoundError: [Errno 2] No such file or directory: '/Library/Frameworks/Python.framework/Versions/3.8/etc/openssl'
很清楚这个错误在说什么:他们没有安装 python (3.8),所以它不能把 ssl 证书放在任何地方(这是因为应用程序在 python 3.8 环境中运行)。
顺便说一下,错误中提到的路径是ssl.get_default_verify_paths().openssl_cafile给出的路径的目录名.
我不是非常精通网络连接的细节和类似的东西,所以我不知道这些证书的确切作用。这是我的问题:
如果用户在他们的计算机上安装 python,是否可以让它工作?
IE。我可以将 ssl 证书添加到应用程序的本地 python 版本(据我所知,在我的应用程序中,python 只是一个捆绑的大型 exec 文件)?文件系统深处是否有我可以放置证书以让不和谐连接发生的地方? .几乎任何解决方案都会受到赞赏。
附加信息:
我安装证书的代码:
STAT_0o775 = (stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
                  | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP
                  | stat.S_IROTH | stat.S_IXOTH)

    openssl_dir, openssl_cafile = os.path.split(
        ssl.get_default_verify_paths().openssl_cafile)
    os.chdir(openssl_dir) #Error happens here
    relpath_to_certifi_cafile = os.path.relpath(certifi.where())
    print(" -- removing any existing file or link")
    try:
        os.remove(openssl_cafile)
    except FileNotFoundError:
        pass
    print(" -- creating symlink to certifi certificate bundle")
    os.symlink(relpath_to_certifi_cafile, openssl_cafile)
    print(" -- setting permissions")
    os.chmod(openssl_cafile, STAT_0o775)
    print(" -- update complete")
当用户没有安装正确的证书时 discord.py 抛出的错误:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/aiohttp/connector.py", line 969, in _wrap_create_connection
    return await self._loop.create_connection(*args, **kwargs)  # type: ignore  # noqa
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/base_events.py", line 1050, in create_connection
    transport, protocol = await self._create_connection_transport(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/base_events.py", line 1080, in _create_connection_transport
    await waiter
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/sslproto.py", line 529, in data_received
    ssldata, appdata = self._sslpipe.feed_ssldata(data)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/asyncio/sslproto.py", line 189, in feed_ssldata
    self._sslobj.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/ssl.py", line 944, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1125)
如果您需要更多信息,请告诉我。

最佳答案

好的。这非常困难,但经过大量研究后我得到了答案。 ssl在 python 中基本上只是 openSSL 的一组绑定(bind).当你这样做 import ssl , 它构建了一个 openSSL环境(我不认为我在这里使用了完全正确的词)。如您所见,它默认为 openSSL Python 中的文件夹因为从 python 的角度来看,这就是 openSSL保留其证书。原来,ssl.DefaultVerifyPaths对象有其他属性,即cafile .这就是我如何根据需要制作通往证书的路径。你看,当openSSL构建时,它会查找环境变量 SSL_CERT_FILE .只要我用 os.environ 设置该变量在我导入 ssl 之前,它会起作用,因为 ssl会找到证书。我简化了 installCerts归结为以下几点:

import os
import stat
import certifi

def installCerts():
    os.environ['SSL_CERT_FILE'] = certifi.where()
    import ssl
    # ssl build needs to happen after enviro var is set
    STAT_0o775 = (stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
                  | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP
                  | stat.S_IROTH | stat.S_IXOTH)
    cafile = ssl.get_default_verify_paths().cafile
    os.chmod(cafile, STAT_0o775)
它现在似乎可以在其他人的计算机上正常工作,而无需他们安装 python。
这个问题帮助了我:
How to change the 'cafile' argument in the ssl module in Python3?

关于python-3.x - 在应用程序中为 discord.py 安装 ssl 证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71418602/

相关文章:

c# - HttpListenerRequest 未返回客户端证书

python - 输出错误: Find the longest path in a matrix with given constraints

django - 如何在 Django Rest Framework 中使用 LimitOffSetPagination 而不是 PageNumberPagination?

ios - 在类中定义的闭包中到达 "self"

linux - Neo4j 在 Mac 上构建失败

android - 仅信任 CA 颁发的特定证书 - Android

php - 安全地更新证书颁发机构证书

python - 如何计算列表中元素的数量并创建新列?

Pythonic 方法来计算列表中特定邻居的数量

macos - Docker Mac 替代 --net=host