如何将企业根证书集成到PyInstaller打包的可执行文件中?
解决PyInstaller打包后企业自签名CA证书集成问题
针对你遇到的[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain错误,以下是几种可靠的解决方案,确保未配置CA信任的用户在VPN环境下也能正常使用打包后的程序:
方案一:自定义CA证书包并全局指定
该方法从根源替换默认CA证书源,适用于所有依赖SSL验证的库:
创建自定义CA证书文件
- 复制certifi包中
cacert.pem的全部内容到新文件(命名为my_cacerts.pem) - 将企业自签名证书内容(需为PEM格式,包含
-----BEGIN CERTIFICATE-----和-----END CERTIFICATE-----标记)追加到my_cacerts.pem末尾
- 复制certifi包中
打包时嵌入自定义证书
使用PyInstaller的--add-data参数将证书嵌入可执行文件,根据操作系统调整分隔符:- Windows:
pyinstaller --onefile --add-data "my_cacerts.pem;." your_script.py - Linux/macOS:
pyinstaller --onefile --add-data "my_cacerts.pem:." your_script.py
- Windows:
代码中配置证书路径
在程序开头添加路径处理逻辑,让系统和依赖库使用自定义证书:import os import sys import certifi def get_resource_path(relative_path): # 适配PyInstaller onefile模式的临时解压路径 try: base_path = sys._MEIPASS except Exception: base_path = os.path.abspath(".") return os.path.join(base_path, relative_path) custom_ca_path = get_resource_path("my_cacerts.pem") # 方式1:设置全局SSL环境变量 os.environ["SSL_CERT_FILE"] = custom_ca_path # 方式2:替换certifi默认证书路径(兼容硬依赖certifi的库) certifi.where = lambda: custom_ca_path
方案二:针对uszipcode库单独配置
如果错误仅出现在uszipcode的请求环节,可直接给它的requests会话指定证书:
from uszipcode import SearchEngine import requests import os import sys def get_resource_path(relative_path): try: base_path = sys._MEIPASS except Exception: base_path = os.path.abspath(".") return os.path.join(base_path, relative_path) custom_ca_path = get_resource_path("my_cacerts.pem") # 创建带自定义证书的requests会话 custom_session = requests.Session() custom_session.verify = custom_ca_path # 让uszipcode使用该会话 search_engine = SearchEngine(session=custom_session) # 后续查询示例 zip_info = search_engine.by_zipcode("10001")
注意事项
- 不要直接修改certifi自带的
cacert.pem,certifi更新时会覆盖该文件,需独立维护自定义证书 - 测试时务必在未配置企业CA信任的机器上,连接VPN验证程序功能
- onefile模式下,程序运行时会将打包文件解压到临时目录,必须通过
get_resource_path函数获取正确的证书位置
内容的提问来源于stack exchange,提问作者carolyng11
相关产品推荐
相关产品推荐

