错误信息
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: CA cert does not include key usage extension
在升级到 Python 3.13 或更高版本后出现;更早的版本不设置这个严格标志。消息后面跟着源代码位置,例如“(_ssl.c:1082)”。openssl verify -x509_strict 把同一项检查报告为“error 92 at 1 depth lookup: CA cert does not include key usage extension”。
Python 3.13+ ssl module — VERIFY_X509_STRICT in create_default_context(), X509_V_ERR_CA_CERT_MISSING_KEY_USAGE (92)
含义
从 Python 3.13 开始,ssl.create_default_context() 会启用 OpenSSL 的严格 X.509 检查(VERIFY_X509_STRICT)。按照 RFC 5280 的要求,其中一项检查规定每张 CA 证书都必须带有允许对证书签名的 keyUsage 扩展。你的 CA 证书没有 keyUsage,所以即使该 CA 被显式信任,在 Python 3.12 上正常的证书链现在也会被拒绝。
原因
直接用 openssl req -x509 创建的 CA
常见OpenSSL 的默认配置会为自签名证书添加 basicConstraints,但不添加 keyUsage。无数教程正是用这种方式创建私有 CA 的,一些测试夹具和开发工具也是如此。
客户端升级到了 Python 3.13 或更高版本
常见证书没有变,是验证方变得更严格了。切换到 python:3.13+ 的容器基础镜像和 CI 运行器,在 PKI 没有任何改动的情况下就会暴露出这个问题。
较旧的内部 PKI 或设备内置的 CA
偶见一些由设备生成的 CA 证书和较旧的企业 CA 证书省略了 keyUsage。在不执行严格检查的客户端中,它们仍能正常使用。
修复方法
- 1.
确认缺少的是哪个扩展
输出 CA 的 basicConstraints 和 keyUsage,并运行 openssl verify -x509_strict,一次性查看所有严格模式下的失败项。
bash openssl x509 -in ca.pem -noout -ext basicConstraints,keyUsage # Same strict checks as Python 3.13+, without Python: openssl verify -x509_strict -CAfile ca.pem server.pem - 2.
带上 keyUsage 重新签发 CA 证书
用 keyUsage = critical, keyCertSign, cRLSign(并把 basicConstraints 设为 critical)重新签名 CA。只要保持密钥和主体不变,它已签发的证书仍能链接到新的 CA 证书;把新的 CA 文件分发给客户端。
bash # A CA certificate with the extensions RFC 5280 requires openssl req -x509 -new -key ca.key -days 3650 -subj "/CN=Example Private CA" \ -addext "basicConstraints=critical,CA:TRUE" \ -addext "keyUsage=critical,keyCertSign,cRLSign" \ -out ca.pem # Reusing the old key and subject keeps already issued certificates verifiable. - 3.
临时规避方案:为这个上下文清除 VERIFY_X509_STRICT
清除这个标志会为单个上下文恢复 Python 3.12 的行为。这与关闭验证不同,但它确实会接受违反 RFC 5280 的证书;CA 修复后就应去掉这项设置。
python # Temporary workaround while the CA is reissued: the chain, dates and host name # are still verified, only the RFC 5280 profile checks are relaxed. import ssl ctx = ssl.create_default_context(cafile="ca.pem") ctx.verify_flags &= ~ssl.VERIFY_X509_STRICT
相关错误
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Basic Constraints o…Python 3.13+ ssl module[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Missing Authority K…Python 3.13+ ssl module[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local…Python ssl module (OpenSSL)