Mensaje de error
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Basic Constraints of CA cert not marked critical
Solo lo imprimen los clientes que activan la comprobación estricta: Python 3.13 y posteriores de forma predeterminada, y openssl verify -x509_strict. Python añade una ubicación en el código fuente, como «(_ssl.c:1082)».
Python 3.13+ ssl module — VERIFY_X509_STRICT in create_default_context(), X509_V_ERR_CA_BCONS_NOT_CRITICAL
Qué significa
Python 3.13 y posteriores verifican con el modo X.509 estricto de OpenSSL, que aplica la regla del RFC 5280 según la cual la extensión basicConstraints de un certificado de CA debe estar marcada como crítica. La CA de tu cadena tiene basicConstraints CA:TRUE sin el indicador critical, así que OpenSSL rechaza la cadena aunque la CA sea de confianza.
Por qué ocurre
La CA se creó a partir de un perfil sin «critical»
frecuenteUna sección de configuración de OpenSSL con basicConstraints = CA:TRUE (en lugar de critical,CA:TRUE), o una herramienta de CA con una plantilla que no cumple la norma, produce certificados de CA de este tipo.
El cliente pasó a Python 3.13 o posterior
frecuenteLas versiones anteriores de Python no establecían VERIFY_X509_STRICT, así que la misma CA funcionaba hasta la actualización.
Una CA intermedia de la cadena tiene el defecto
ocasionalLa comprobación se aplica a todos los certificados de CA de la ruta, incluidos los intermedios emitidos por una raíz que sí cumple la norma.
Cómo solucionarlo
- 1.
Encontrar el certificado que no cumple la norma
Imprime basicConstraints de cada CA de la cadena; hay que volver a emitir la que no tenga «critical». openssl verify -x509_strict muestra todos los problemas del modo estricto.
bash openssl x509 -in ca.pem -noout -ext basicConstraints # X509v3 Basic Constraints: <- no "critical" here is the problem # CA:TRUE openssl verify -x509_strict -CAfile ca.pem server.pem - 2.
Volver a emitir la CA con basicConstraints marcada como crítica
Vuelve a firmar el certificado de la CA con basicConstraints = critical, CA:TRUE y una extensión keyUsage. Conservar la misma clave y el mismo sujeto permite que los certificados existentes se sigan verificando con él.
bash 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 - 3.
Solución provisional: quitar VERIFY_X509_STRICT
Restablece el comportamiento anterior a Python 3.13 en un solo contexto mientras se corrige la CA. La verificación de la cadena, de las fechas de validez y del nombre de host sigue activa.
python # Temporary workaround until the CA is reissued (chain, dates and name are still checked) import ssl ctx = ssl.create_default_context(cafile="ca.pem") ctx.verify_flags &= ~ssl.VERIFY_X509_STRICT