Saltar al contenido
ecdsa.com
Python ssl module (OpenSSL)cryptography de Python

Mensaje de error

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate

También se muestra como

  • [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate

Python añade la ubicación en el código fuente C, por ejemplo «(_ssl.c:1082)». No lo confundas con «self-signed certificate in certificate chain», que indica una cadena de CA que termina en una raíz que no es de confianza. OpenSSL 1.1.1 lo escribe «self signed».

Python ssl module (OpenSSL) — ssl.SSLCertVerificationError, X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT (18)

Qué significa

El servidor presentó un único certificado autofirmado (su emisor es él mismo) que no está en el conjunto de CA de confianza de este contexto. No hay ninguna CA que buscar, así que OpenSSL falla en la profundidad 0. Es típico de servidores de desarrollo, dispositivos dedicados e instalaciones recién hechas; la solución es confiar deliberadamente en ese certificado o sustituirlo.

Por qué ocurre

Cómo solucionarlo

  1. 1.

    Confiar en este único certificado para este cliente

    Carga el propio certificado del servidor como cafile. Las comprobaciones del nombre de host y de las fechas siguen activas, y solo se acepta exactamente este certificado.

    python
    import ssl, urllib.request
    
    # Trust exactly this certificate (fetched and fingerprint-checked out of band)
    ctx = ssl.create_default_context(cafile="api.example.com.pem")
    urllib.request.urlopen("https://api.example.com:8443/", context=ctx)
  2. 2.

    Obtener el certificado y comprobar su huella digital

    Compara la huella digital SHA-256 con el valor que muestra la consola del dispositivo o que te da su administrador antes de confiar en el archivo.

    bash
    openssl s_client -connect api.example.com:8443 -servername api.example.com </dev/null 2>/dev/null \
      | openssl x509 -out api.example.com.pem
    openssl x509 -in api.example.com.pem -noout -fingerprint -sha256   # compare with the server's console
  3. 3.

    Desarrollo: usar una CA local en su lugar

    Una CA local te permite confiar en una sola raíz y emitir certificados correctamente firmados para cada host de desarrollo, así que ningún cliente necesita excepciones por certificado.

    bash
    # Development: one local CA, many certificates (mkcert installs the CA for you)
    mkcert -install
    mkcert api.example.test
    export SSL_CERT_FILE="$(mkcert -CAROOT)/rootCA.pem"
  4. 4.

    Diagnóstico temporal: desactivar la verificación en una prueba

    check_hostname = False y CERT_NONE desactivan todas las comprobaciones y aceptan cualquier certificado, incluido uno presentado por un atacante. Úsalo solo para confirmar que la confianza es el único problema y después elimínalo.

    python
    # Temporary diagnostic only: proves trust is the sole problem. Never ship this.
    import ssl
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE

Errores relacionados

Explorar toda la base de datos de errores de firma