Choisir entre un certificat auto-signé et un certificat signé par une AC revient à se demander qui se porte garant du lien entre une clé publique et un nom. Un certificat auto-signé est signé avec sa propre clé : il prouve seulement que son détenteur possède cette clé, et un client ne lui fait confiance que si on lui a demandé de faire confiance à ce certificat précis. Un certificat signé par une AC est signé par une autorité de certification dont le client approuve déjà la racine : une AC publique pour Internet, ou une AC privée que vous exploitez et distribuez vous-même.
Vue d’ensemble
| Auto-signé | AC privée | AC publique | |
|---|---|---|---|
| Qui signe le certificat feuille | Sa propre clé | Votre AC racine ou intermédiaire | Une AC présente dans les magasins de certificats racines des navigateurs et des OS |
| Comment les clients apprennent à lui faire confiance | Chaque client épingle ou installe ce certificat précis | Installation d’une seule racine (MDM, gestion de configuration, image de conteneur) | Déjà approuvé par défaut |
| Rotation du certificat feuille | Chaque client doit être mis à jour | Transparente pour les clients | Transparente pour les clients |
| Révocation | Aucune ; il faut le retirer de chaque client | Vos propres CRL, OCSP ou des durées de vie courtes | CRL publiées par l’AC |
| Noms qu’il peut porter | N’importe quel nom | Tout nom autorisé par les contraintes de la racine | Noms de domaine publics et adresses IP publiques uniquement |
| Limites de durée de vie | Aucune côté navigateurs ; les plateformes Apple plafonnent à 825 jours les certificats TLS émis depuis juillet 2019 | Même plafond de 825 jours sur les plateformes Apple | 200 jours aujourd’hui, 47 jours à partir de mars 2029 |
| Certificate Transparency | Non journalisé | Non journalisé | Journalisé publiquement, avec chaque nom d’hôte |
| Coût et effort | Aucun au départ ; élevé à chaque rotation | Exploitation de l’AC, protection de sa clé | Gratuit avec ACME ; exige une validation DNS ou HTTP |
| Outils courants | openssl req -x509, mkcert pour le développement local | step-ca, HashiCorp Vault PKI, AC privées des fournisseurs cloud, cert-manager | Let’s Encrypt et les autres AC ACME |
Comment les clients décident de faire confiance à un certificat
La validation du chemin (RFC 5280 §6) construit une chaîne depuis le certificat du serveur jusqu’à une ancre de confiance du magasin de certificats racines du client, en vérifiant au passage chaque signature, la période de validité, les contraintes de base, l’utilisation de la clé et les contraintes de noms. Un certificat auto-signé a le même émetteur et le même sujet, et il est signé par sa propre clé : la seule chaîne possible est donc le certificat lui-même. Il n’est validé que si ce certificat est lui-même une ancre de confiance pour le client, et c’est exactement ce que signifie « épingler » ou « installer » un certificat auto-signé.
Un certificat feuille signé par une AC est signé par une AC intermédiaire, elle-même rattachée à une AC racine. Le client n’a jamais besoin de connaître le certificat feuille à l’avance : la racine lui suffit. C’est cette indirection qui rend possibles la rotation, la révocation et l’automatisation.
Le script ci-dessous, exécuté avec OpenSSL 3.6.5, crée un certificat auto-signé, une racine privée limitée aux noms sous .internal et deux certificats feuilles signés par cette racine.
#!/bin/sh
dir=$(mktemp -d)
cd "$dir" || exit 1
P256="-newkey ec -pkeyopt ec_paramgen_curve:P-256 -noenc"
# 1. Self-signed server certificate
openssl req -x509 $P256 -keyout self.key -out self.pem -days 30 \
-subj "/CN=dev.internal" \
-addext "subjectAltName=DNS:dev.internal,IP:127.0.0.1" \
-addext "basicConstraints=critical,CA:FALSE" 2>/dev/null
openssl verify self.pem
openssl verify -CAfile self.pem self.pem
# 2. Private root CA limited to .internal names
openssl req -x509 $P256 -keyout ca.key -out ca.pem -days 3650 \
-subj "/CN=Example Internal Root" \
-addext "keyUsage=critical,keyCertSign,cRLSign" \
-addext "nameConstraints=critical,permitted;DNS:.internal" 2>/dev/null
# 3. Two server certificates signed by that CA
for name in api.internal www.example.com; do
openssl req -x509 $P256 -CA ca.pem -CAkey ca.key -keyout "$name.key" \
-out "$name.pem" -days 90 -subj "/CN=$name" \
-addext "subjectAltName=DNS:$name" \
-addext "basicConstraints=critical,CA:FALSE" \
-addext "extendedKeyUsage=serverAuth" 2>/dev/null
done
openssl verify api.internal.pem
openssl verify -CAfile ca.pem api.internal.pem
openssl verify -CAfile ca.pem www.example.com.pem
cd / && rm -rf "$dir"
CN=dev.internal
error 18 at 0 depth lookup: self-signed certificate
error self.pem: verification failed
self.pem: OK
CN=api.internal
error 20 at 0 depth lookup: unable to get local issuer certificate
error api.internal.pem: verification failed
api.internal.pem: OK
CN=www.example.com
error 47 at 0 depth lookup: permitted subtree violation
error www.example.com.pem: verification failed
Le certificat auto-signé n’est vérifié que lorsqu’il est fourni comme sa propre ancre de confiance. Le certificat feuille de l’AC privée est vérifié dès que la racine est approuvée, et les contraintes de noms de la racine empêchent cette AC de se porter garante de www.example.com, ce qui limite les dégâts si la clé de l’AC venait un jour à être détournée. Notez que openssl req -x509 marque par défaut les certificats comme AC, par l’intermédiaire de son fichier de configuration ; le CA:FALSE explicite empêche le certificat de serveur auto-signé d’être utilisable comme émetteur.
Ce que disent les clients quand ils ne font pas confiance au certificat
Nous avons connecté cinq clients à un serveur local présentant tour à tour chaque certificat, sans rien ajouter à leurs magasins de confiance (20 octobre 2026, macOS).
| Client | Certificat auto-signé | Certificat feuille d’une AC privée non approuvée |
|---|---|---|
| Node.js 26.10 | DEPTH_ZERO_SELF_SIGNED_CERT | UNABLE_TO_VERIFY_LEAF_SIGNATURE |
| Python 3.14 (OpenSSL 3.6.5) | certificate verify failed: self-signed certificate | certificate verify failed: unable to get local issuer certificate |
| Go 1.25 (vérificateur de macOS) | x509: certificate signed by unknown authority | x509: “localhost” certificate is not trusted |
| curl 8.7.1 (LibreSSL) | (60) SSL certificate problem: self signed certificate | (60) SSL certificate problem: unable to get local issuer certificate |
OpenSSL 3.6.5 s_client | Verify return code: 18 (self-signed certificate) | Verify return code: 20 (unable to get local issuer certificate) |
Les navigateurs affichent NET::ERR_CERT_AUTHORITY_INVALID (Chrome) ou MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT (Firefox). La solution n’est jamais de désactiver la vérification (NODE_TLS_REJECT_UNAUTHORIZED=0, verify=False, InsecureSkipVerify, curl -k) : cela supprime l’authentification de toutes les connexions qu’établit le processus. Donnez plutôt au client le certificat ou la racine qu’il doit approuver (ca: dans Node.js, cafile= en Python, un pool RootCAs personnalisé en Go, --cacert dans curl), ou installez la racine dans le magasin du système d’exploitation. Un certificat sans nom DNS dans l’extension Subject Alternative Name échoue autrement : Chrome a cessé de comparer le nom d’hôte au nom commun à partir de la version 58 (2017), et les plateformes Apple depuis iOS 13 et macOS 10.15.
La voie médiane : une AC privée
Une AC privée conserve le principal avantage de l’auto-signature (aucun tiers extérieur, n’importe quel nom interne, aucune journalisation publique) tout en supprimant son principal coût (redistribuer la confiance à chaque rotation). Règles pratiques :
- Gardez la racine hors ligne et émettez depuis une AC intermédiaire ; une AC intermédiaire compromise peut être remplacée sans intervenir sur chaque client.
- Limitez les noms à vos zones internes, comme dans la démonstration, et restreignez au maximum
pathlenet l’utilisation de la clé. - Automatisez les certificats feuilles : step-ca, Vault PKI et cert-manager peuvent émettre via ACME ou leurs propres API, si bien que les certificats feuilles peuvent ne vivre que quelques heures ou quelques jours et que la révocation devient inutile.
- Respectez malgré tout les règles des clients : pour les certificats TLS émis depuis le 1er juillet 2019, les plateformes Apple exigent un nom DNS dans le SAN, l’utilisation étendue de la clé
serverAuthet une validité de 825 jours au plus, y compris avec des racines privées ; la limite de 398 jours ne s’applique qu’aux racines publiquement approuvées. - Planifiez la distribution de la racine : les magasins des systèmes d’exploitation, les keystores Java, les images de conteneur, les navigateurs dotés de leur propre magasin (Firefox) et les logiciels qui embarquent leur propre bundle de certificats (le paquet
certifisur lequel reposerequestsen Python, et Node.js, qui utilise son bundle Mozilla intégré sauf s’il est lancé avec--use-system-ca) ont chacun besoin de la racine.
Là où une AC publique ne peut rien
Les AC publiques n’ont pas le droit d’émettre des certificats contenant des noms internes ou des adresses IP réservées (Baseline Requirements §4.2.2). Des noms comme printer.local, les noms d’hôte à une seule étiquette, 10.0.0.5 ou tout ce qui se trouve sous .internal, que l’ICANN a définitivement réservé à un usage privé le 29 juillet 2024, ne peuvent donc provenir que d’une AC privée ou d’un certificat auto-signé. Les hôtes internes qui portent des noms publics (par exemple db.corp.example.com) peuvent obtenir des certificats publics grâce au challenge DNS-01 sans être accessibles depuis Internet, mais chaque nom apparaît alors dans les journaux publics Certificate Transparency, ce qui révèle votre topologie interne à quiconque les consulte.
Quand choisir l’un ou l’autre
- Sites web publics, API et serveurs de messagerie : AC publique avec ACME.
- Services internes, maillages de services, mTLS entre charges de travail : AC privée avec des certificats feuilles de courte durée.
- Développement local : une AC de développement local comme
mkcert, qui installe sa racine dans vos propres magasins de confiance, plutôt que des certificats auto-signés que chaque outil rejette à sa manière. - Appareils et équipements au premier démarrage : un certificat auto-signé dont l’utilisateur ou le système de provisionnement vérifie l’empreinte une fois, suivi d’un enrôlement auprès d’une AC privée.
- Fixtures de test : des certificats auto-signés générés par le test lui-même et transmis explicitement au client testé.
- Partenaires et intégrations B2B en mTLS : une AC privée dédiée à cette relation, jamais votre racine interne générale.
Notes de migration
- Recensez les certificats auto-signés en service : analysez les points de terminaison internes et collectez les certificats que les clients épinglent ; le décodeur de certificats affiche l’émetteur, les SAN et l’expiration.
- Mettez en place une AC privée avec une racine hors ligne et une AC intermédiaire émettrice, limitée à vos domaines internes ; générez les demandes avec le générateur de CSR.
- Distribuez la racine avant de basculer le moindre serveur, puis remplacez les certificats feuilles service par service ; le constructeur de chaînes confirme que chaque serveur envoie son certificat intermédiaire.
- Supprimez les contournements non sécurisés (
-k,verify=False,InsecureSkipVerify) dès que les clients font confiance à la racine, et faites une recherche dans le code pour qu’ils ne reviennent pas. - Faites passer les noms exposés au public à une AC publique avec ACME, et conservez l’épinglage (le cas échéant) sur les clés plutôt que sur les certificats ; le générateur d’empreintes SPKI calcule des empreintes à épingler qui survivent au renouvellement avec la même clé.
Références
- RFC 5280 §6, validation du chemin de certification et §4.2.1.10, contraintes de noms
- Baseline Requirements du CA/Browser Forum, §4.2.2
- Apple : exigences relatives aux certificats approuvés dans iOS 13 et macOS 10.15
- Apple : à propos des futures limites appliquées aux certificats approuvés (398 jours)
- Résolution 2024.07.29.06 du conseil d’administration de l’ICANN réservant .INTERNAL
- RFC 9162, Certificate Transparency 2.0
- RFC 8555, ACME