Zum Inhalt springen
ecdsa.com
Python ssl module (OpenSSL)Python cryptography

Fehlermeldung

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

Auch ausgegeben als

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

Python hängt die Position im C-Quellcode an, etwa „(_ssl.c:1082)“. Nicht zu verwechseln mit „self-signed certificate in certificate chain“: Das bedeutet eine CA-Kette, die in einem nicht vertrauenswürdigen Root-Zertifikat endet. OpenSSL 1.1.1 schreibt „self signed“.

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

Was der Fehler bedeutet

Der Server hat ein einzelnes selbstsigniertes Zertifikat vorgelegt (sein Aussteller ist es selbst), das nicht zu den vertrauenswürdigen CAs dieses Kontexts gehört. Es gibt keine CA, die sich nachschlagen ließe, deshalb scheitert OpenSSL auf Tiefe 0. Typisch für Entwicklungsserver, Appliances und frische Installationen; die Abhilfe besteht darin, diesem Zertifikat bewusst zu vertrauen oder es zu ersetzen.

Warum der Fehler auftritt

So behebst du den Fehler

  1. 1.

    Genau diesem Zertifikat für diesen Client vertrauen

    Lade das Zertifikat des Servers selbst als cafile. Die Prüfungen von Hostname und Gültigkeitszeitraum bleiben aktiv, und akzeptiert wird nur genau dieses Zertifikat.

    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.

    Zertifikat abrufen und Fingerabdruck prüfen

    Vergleiche den SHA-256-Fingerabdruck mit dem Wert, den die Konsole des Geräts anzeigt oder den dir sein Admin nennt, bevor du der Datei vertraust.

    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.

    Entwicklung: stattdessen eine lokale CA verwenden

    Mit einer lokalen CA vertraust du einem einzigen Root-Zertifikat und stellst für jeden Entwicklungshost ordentlich signierte Zertifikate aus, sodass kein Client Ausnahmen für einzelne Zertifikate braucht.

    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.

    Vorübergehende Diagnose: Prüfung in einem Test abschalten

    check_hostname = False und CERT_NONE schalten jede Prüfung ab und akzeptieren jedes Zertifikat, auch eines, das ein Angreifer vorlegt. Verwende das nur, um zu bestätigen, dass das Vertrauen das einzige Problem ist, und entferne es danach wieder.

    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

Verwandte Fehler

Gesamte Signaturfehler-Datenbank durchsuchen