Перейти к содержимому
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() включает строгие проверки X.509 в OpenSSL (VERIFY_X509_STRICT). Одна из них требует, чтобы в каждом сертификате CA было расширение keyUsage, разрешающее подписывать сертификаты, — как предписывает RFC 5280. В вашем сертификате CA нет keyUsage, поэтому цепочка, которая работала на Python 3.12, теперь отклоняется, хотя этому CA явно доверяют.

Почему это происходит

Как исправить

  1. 1.

    Выясните, какого расширения не хватает

    Выведите basicConstraints и keyUsage сертификата CA и запустите 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.

    Перевыпустите сертификат CA с keyUsage

    Подпишите CA заново с keyUsage = critical, keyCertSign, cRLSign (и basicConstraints с пометкой critical). Если сохранить тот же ключ и субъект, сертификаты, которые он уже выпустил, по-прежнему выстраиваются в цепочку до нового сертификата 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

Связанные ошибки

Открыть всю базу ошибок подписей