MACBOOK下出现:OSError: [Errno socket error] [SSL: CERTIFICATE_VERIFY_FAILED] certific


环境:macbook pro
在使用kivy打包APK的时候,编译过程出现:


kcleung@macone pykivy % buildozer -v android debug
# Check configuration tokens
# Ensure build layout
# Check configuration tokens
# Preparing build
# Check requirements for android
# Search for Git (git)
#  -> found at /usr/local/Cellar/git/2.45.0/bin/git
# Search for Cython (cython)
#  -> found at /Library/Frameworks/Python.framework/Versions/3.12/bin/cython
# Search for Java compiler (javac)
#  -> found at /usr/bin/javac
# Search for Java keytool (keytool)
#  -> found at /usr/bin/keytool
# Install platform
# Run ['git', 'config', '--get', 'remote.origin.url']
# Cwd /Users/kcleung/Documents/del/pykivy/.buildozer/android/platform/python-for-android
https://github.com/kivy/python-for-android.git
# Run ['git', 'branch', '-vv']
# Cwd /Users/kcleung/Documents/del/pykivy/.buildozer/android/platform/python-for-android
* master 957a3e5f [origin/master] Merge pull request #2959 from kivy/release-2024.01.21
# Run ['/Library/Frameworks/Python.framework/Versions/3.12/bin/python3', '-m', 'pip', 'install', '-q', '--user', 'appdirs', 'colorama>=0.3.3', 'jinja2', 'sh>=1.10, <2.0; sys_platform!="win32"', 'build', 'toml', 'packaging', 'setuptools']
# Cwd None
# Apache ANT found at /Users/kcleung/.buildozer/android/platform/apache-ant-1.9.4
# Android SDK found at /Users/kcleung/.buildozer/android/platform/android-sdk
# Recommended android's NDK version by p4a is: 25b
# Android NDK is missing, downloading
# Downloading https://dl.google.com/android/repository/android-ndk-r25b-darwin.zip
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/urllib/request.py", line 1788, in open
    return getattr(self, name)(url)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/urllib/request.py", line 2002, in open_https
    return self._open_generic_http(self._https_connection, url, data)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/urllib/request.py", line 1943, in _open_generic_http
    http_conn.request("GET", selector, headers=headers)
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/http/client.py", line 1336, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/http/client.py", line 1382, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/http/client.py", line 1331, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/http/client.py", line 1091, in _send_output
    self.send(msg)
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/http/client.py", line 1035, in send
    self.connect()
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/http/client.py", line 1477, in connect
    self.sock = self._context.wrap_socket(self.sock,
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/ssl.py", line 455, in wrap_socket
    return self.sslsocket_class._create(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/ssl.py", line 1042, in _create
    self.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/ssl.py", line 1320, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.12/bin/buildozer", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/buildozer/scripts/client.py", line 13, in main
    Buildozer().run_command(sys.argv[1:])
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/buildozer/__init__.py", line 1024, in run_command
    self.target.run_commands(args)
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/buildozer/target.py", line 93, in run_commands
    func(args)
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/buildozer/target.py", line 103, in cmd_debug
    self.buildozer.prepare_for_build()
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/buildozer/__init__.py", line 172, in prepare_for_build
    self.target.install_platform()
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/buildozer/targets/android.py", line 615, in install_platform
    self._install_android_ndk()
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/buildozer/targets/android.py", line 438, in _install_android_ndk
    self.buildozer.download(url,
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/buildozer/__init__.py", line 658, in download
    urlretrieve(url, filename, report_hook)
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/urllib/request.py", line 1822, in retrieve
    fp = self.open(url, data)
         ^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/urllib/request.py", line 1794, in open
    raise OSError('socket error', msg) from msg
OSError: [Errno socket error] [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1000)

大概意思就是,无法使用本地的证书发布者证书进行验证。

解决方案:

在 macOS 中如果执行 Install Certificates.command 失败,或者 certifi 也无效,可能是 Python 安装的环境和系统证书之间的通信出现了问题。这里有几个可能的解决办法。

1. 手动执行 Install Certificates.command

Install Certificates.command 是在使用 macOS 安装 Python 时附带的一个脚本,旨在解决 Python 环境中的证书问题。你可以手动定位并执行它:

步骤:

  1. 打开 Finder,进入到 Python 安装目录。这个目录通常在 /Applications 文件夹下,例如:

    /Applications/Python\ 3.x/
  2. 在该目录中,你应该能找到一个文件 Install Certificates.command。双击该文件,它会启动终端,并自动执行证书安装脚本。

如果双击没有效果,你可以尝试在终端中手动执行:

cd "/Applications/Python 3.x/"
./Install\ Certificates.command

2. 使用 Homebrew 重新安装 Python

有时通过官方安装器安装的 Python 可能会有证书问题,你可以考虑通过 Homebrew 安装 Python,它通常会更好地处理 macOS 的证书问题。

安装步骤:

  1. 使用 Homebrew 安装 Python:

    brew install python
  2. 确保你使用的是 Homebrew 安装的 Python 版本,可以通过以下命令来验证:

    which python3

    输出路径应类似于 /usr/local/bin/python3/opt/homebrew/bin/python3

  3. 使用 Homebrew 安装 Python 后,根证书通常会自动处理好,但你可以再次验证 Python SSL 模块是否工作正常:

    python3 -m ssl

3. 下载并手动配置证书

如果 certifi 或其他方法依然无法解决,你可以尝试手动获取最新的根证书并配置它们。

步骤:

  1. 下载最新的证书颁发机构包:

    • 使用 certifi 提供的证书文件路径:
    python3 -m certifi

它会返回证书文件的位置,例如 /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/certifi/cacert.pem

  1. 手动设置 SSL_CERT_FILE 环境变量以指向 certifi 的证书文件。

    编辑 .bash_profile.zshrc 文件,并添加如下内容:

    export SSL_CERT_FILE=$(python3 -m certifi)

    然后运行:

    source ~/.bash_profile  # or source ~/.zshrc

4. 忽略 SSL 验证(临时解决方案)

如果你暂时无法解决这个问题,且是为了开发用途,可以临时忽略 SSL 证书验证,但请记住,这是不安全的做法:

临时忽略证书验证:

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

此代码将告诉 Python 临时忽略 SSL 验证。这仅适用于开发或测试环境,不推荐在生产环境中使用

总结

  • 如果 Install Certificates.command 无法执行,尝试使用 Homebrew 安装 Python 或手动配置证书。
  • 确保系统环境变量 SSL_CERT_FILE 指向正确的证书路径。
  • 如果所有方法都失败,可以考虑临时禁用 SSL 验证,但这存在安全隐患。

原文链接:https://blog.yongit.com/note/1573126.html