Pular para o conteúdo
ecdsa.com
Python 3.13+ ssl modulePython (cryptography)

Mensagem de erro

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: CA cert does not include key usage extension

Aparece depois da atualização para o Python 3.13 ou posterior; versões anteriores não definem a flag estrita. Vem seguida de uma localização no código-fonte, como “(_ssl.c:1082)”. O openssl verify -x509_strict relata a mesma verificação como “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)

O que significa

Desde o Python 3.13, ssl.create_default_context() ativa as verificações X.509 estritas do OpenSSL (VERIFY_X509_STRICT). Uma delas exige que todo certificado de CA traga uma extensão keyUsage que permita assinar certificados, como a RFC 5280 determina. Seu certificado de CA não tem keyUsage, então uma cadeia que funcionava no Python 3.12 agora é rejeitada, mesmo que a CA esteja explicitamente marcada como confiável.

Por que acontece

Como corrigir

  1. 1.

    Confirmar qual extensão está faltando

    Imprima o basicConstraints e o keyUsage da CA e rode openssl verify -x509_strict para ver todas as falhas do modo estrito de uma vez.

    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.

    Reemitir o certificado da CA com keyUsage

    Assine a CA de novo com keyUsage = critical, keyCertSign, cRLSign (e basicConstraints crítico). Se você mantiver a mesma chave e o mesmo titular, os certificados que ela já emitiu continuam se encadeando ao novo certificado da CA; distribua o novo arquivo da CA para os clientes.

    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.

    Solução temporária: desativar VERIFY_X509_STRICT neste contexto

    Remover a flag restaura o comportamento do Python 3.12 em um único contexto. Isso não é o mesmo que desativar a verificação, mas passa a aceitar certificados que violam a RFC 5280; desfaça a mudança assim que a CA for corrigida.

    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

Erros relacionados

Ver toda a base de erros de assinatura