真正有效的解法是让 pip 信任当前网络环境下的证书链,而非跳过验证;常见原因包括企业代理重签HTTPS、Python未内置完整CA证书、macOS Homebrew安装未关联钥匙串或Windows杀软劫持SSL连接。

直接关掉 SSL 验证不是办法,真正有效的解法是让 pip 信任你当前网络环境下的证书链,而不是跳过验证。
为什么 pip install 会报 SSL certificate verify failed?
这不是 Python 本身的问题,而是 pip 在连接 PyPI(https://pypi.org)时,无法用系统或内置证书验证服务器 TLS 证书。常见于:公司内网代理重签了 HTTPS 流量、Python 嵌入式环境没带完整 CA 证书、macOS 上通过 Homebrew 安装的 Python 没自动关联系统钥匙串、或 Windows 上某些杀毒软件劫持了 SSL 连接。
典型错误信息长这样:SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed
- 别急着加
--trusted-host pypi.org或设PIP_TRUSTED_HOST—— 这等于让 pip 对所有中间人攻击敞开大门 - 也别盲目复制网上说的“把 certifi 路径硬编码进 requests” —— 现代 pip 已不依赖全局 certifi 包做验证
- 关键是定位证书来源:pip 默认用的是
certifi内置证书,但会优先读取环境变量SSL_CERT_FILE或REQUESTS_CA_BUNDLE
怎么让 pip 找到并信任正确的 CA 证书?
先确认你手头有没有可用的证书文件。常见位置:
立即学习“Python免费学习笔记(深入)”;
- Linux/macOS:一般在
/etc/ssl/certs/ca-certificates.crt或/usr/local/etc/openssl/cert.pem - macOS(Homebrew Python):
$(brew --prefix)/etc/openssl/cert.pem - Windows:通常没有现成 bundle,需手动下载 curl 官方 PEM 文件,存为
C:\cacert.pem
然后告诉 pip 用它:
- 临时生效(当前命令):
pip install --cert /path/to/cacert.pem requests - 永久生效(用户级):在
pip.conf(Linux/macOS)或pip.ini(Windows)里加一行:global.cert = /path/to/cacert.pem - 更通用的做法(影响所有基于 urllib3/requests 的工具):设置环境变量
SSL_CERT_FILE=/path/to/cacert.pem
公司代理环境下该怎么处理?
如果走的是企业 HTTPS 代理(比如 Zscaler、Blue Coat),它的中间证书不会出现在公开 CA 列表里。这时不能靠 public PEM,得导出代理设备的根证书:
- 用浏览器访问任意 HTTPS 网站,点击地址栏锁图标 → 查看证书 → 导出为 DER 格式 → 用 OpenSSL 转成 PEM:
openssl x509 -inform DER -in company-root.cer -out company-root.pem - 把生成的
company-root.pem追加到你的本地 CA bundle 末尾(不要覆盖原文件):cat company-root.pem >> /path/to/cacert.pem - 再用上面的方法指定该 bundle 路径即可
注意:有些代理会动态改写 SNI 或拦截 OCSP 请求,此时即使证书正确,pip 仍可能超时失败 —— 这时需要额外加 --retries 0 和调高超时:pip install --timeout 100 --cert /path/to/bundle.pem somepkg
Python 内置证书和 certifi 到底谁在起作用?
Python 3.12+ 自带 ssl.create_default_context() 会优先使用操作系统证书存储(Windows/macOS)或 certifi(Linux)。但 pip 自 22.2 版起已**不再默认依赖 certifi**,而是自带一份精简证书(来自 pip/_vendor/certifi)。所以:
- 升级 pip 不一定能解决证书问题 —— 新版 pip 的内置证书未必包含你的内网 CA
-
pip install certifi后,它不会自动被 pip 使用;除非你显式设置SSL_CERT_FILE指向certifi.where()返回的路径 - 查当前 pip 实际用哪个证书:
python -c "import pip._vendor.certifi; print(pip._vendor.certifi.where())"
最稳妥的方式永远是:明确指定一个你亲自验证过、包含所需根证书的 PEM 文件路径,而不是指望 pip “自动猜对”。


















