Aller au contenu
ecdsa.com
Python ssl module (OpenSSL)cryptography (Python)

Message d’erreur

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

Également affiché sous la forme

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

Python ajoute l’emplacement dans le code source C, par exemple « (_ssl.c:1082) ». À ne pas confondre avec « self-signed certificate in certificate chain », qui désigne une chaîne d’AC se terminant par une racine non approuvée. OpenSSL 1.1.1 l’écrit « self signed ».

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

Ce que cela signifie

Le serveur a présenté un unique certificat auto-signé (son émetteur est lui-même) qui ne figure pas dans l’ensemble des AC approuvées de ce contexte. Il n’y a aucune AC à rechercher : OpenSSL échoue donc à la profondeur 0. C’est typique des serveurs de développement, des équipements et des installations neuves ; la solution consiste à faire confiance délibérément à ce certificat ou à le remplacer.

Pourquoi cela se produit

Comment corriger l’erreur

  1. 1.

    Faire confiance à ce seul certificat pour ce client

    Chargez le certificat du serveur lui-même comme cafile. Les contrôles du nom d’hôte et des dates restent actifs, et seul ce certificat précis est accepté.

    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.

    Récupérer le certificat et vérifier son empreinte

    Avant de faire confiance au fichier, comparez l’empreinte SHA-256 avec la valeur affichée sur la console de l’équipement ou communiquée par son administrateur.

    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.

    Développement : utiliser plutôt une AC locale

    Une AC locale vous permet de faire confiance à une seule racine et d’émettre des certificats correctement signés pour chaque hôte de développement : aucun client n’a alors besoin d’exceptions certificat par certificat.

    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.

    Diagnostic temporaire : désactiver la vérification dans un test

    check_hostname = False et CERT_NONE désactivent tous les contrôles et acceptent n’importe quel certificat, y compris celui que présenterait un attaquant. Ne vous en servez que pour confirmer que la confiance est le seul problème, puis retirez ce réglage.

    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

Erreurs associées

Parcourir toute la base de données des erreurs de signature