跳到主要内容
ecdsa.com
Python 3.13+ ssl modulePython cryptography 库

错误信息

[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 上正常的证书链现在也会被拒绝。

原因

修复方法

  1. 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. 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. 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

相关错误

浏览完整的签名错误库