🛠 Outils IT
🛠 102 outils 📚 53 docs
🤖 Assistant ☀

PKI et gestion des certificats

Périmètre : cette page s'adresse aux ingénieurs qui conçoivent ou exploitent une PKI (interne ou publique). Pour les commandes OpenSSL détaillées, voir OpenSSL - Aide-mémoire avancé ; pour Let's Encrypt côté serveur web, voir Let's Encrypt ; pour la notation TLS publique, voir SSL Labs. Tous les noms (example.com, corp.example.com) et adresses sont fictifs.

1. Fondamentaux X.509 : chaîne et extensions

1.1 La chaîne de confiance

Un certificat X.509 v3 lie une clé publique à une identité, signé par une autorité (AC). Le client construit un chemin de certification du certificat feuille jusqu'à une ancre de confiance présente dans son magasin :

[Racine]  CN=Example Root CA        (auto-signée, dans le magasin de confiance)
   |
   +-- [Intermédiaire] CN=Example Issuing CA 01   (signée par la racine, envoyée par le serveur)
          |
          +-- [Feuille] CN=www.example.com     (signée par l'intermédiaire, envoyée par le serveur)
  • Le serveur doit envoyer la feuille + les intermédiaires, jamais la racine (inutile, et pénalisée par certains audits).
  • Le chaînage se fait par correspondance Issuer DN / Subject DN et surtout Authority Key Identifier (AKI) / Subject Key Identifier (SKI). Deux intermédiaires de même nom mais de clés différentes (renouvellement avec nouvelle clé) sont distingués par l'AKI.
  • Les certificats croisés (cross-signed) permettent plusieurs chemins valides : un client ancien remonte vers une vieille racine, un client récent vers la nouvelle. Le choix du chemin dépend de l'implémentation (CryptoAPI, NSS, OpenSSL, Java, Go n'ont pas le même algorithme de construction).

1.2 Champs et extensions qui comptent

Extension / champRôleValeurs typiquesPiège
subjectAltName (SAN)Identités couvertes : DNS, IP, email, URI, UPNDNS:www.example.com, DNS:example.com, IP:192.0.2.10Les navigateurs ignorent le CN depuis des années : un nom absent du SAN = erreur, même s'il est dans le CN
keyUsage (KU)Opérations cryptographiques autoriséesFeuille RSA : digitalSignature, keyEncipherment ; ECDSA : digitalSignature ; AC : keyCertSign, cRLSignkeyEncipherment sur une clé ECDSA est incohérent ; certains clients stricts rejettent
extendedKeyUsage (EKU)Usages applicatifsserverAuth (1.3.6.1.5.5.7.3.1), clientAuth (.3.2), codeSigning (.3.3), emailProtection (.3.4), Smart Card Logon (1.3.6.1.4.1.311.20.2.2)EKU absent = « tout usage » pour beaucoup d'implémentations (cf. ESC2) ; anyExtendedKeyUsage idem
basicConstraintsDistingue AC et entité finaleAC : critical, CA:TRUE, pathlen:0 ; feuille : CA:FALSEUne feuille sans CA:FALSE explicite est tolérée, mais une AC sans CA:TRUE ne peut rien signer
nameConstraintsRestreint les noms qu'une AC peut émettrepermitted;DNS:.corp.example.comTrès utile pour une AC interne croisée ; mal supporté par de vieux clients si marquée critique
authorityInfoAccess (AIA)Où télécharger le certificat de l'émetteur (caIssuers) et où interroger l'OCSPcaIssuers;URI:http://pki.example.com/pki/issuing01.crtWindows et les navigateurs savent compléter une chaîne via AIA ; OpenSSL, Java, curl, Go non : une chaîne incomplète « marche dans Chrome » mais casse les API
crlDistributionPoints (CDP)URL de la CRL de l'émetteurURI:http://pki.example.com/pki/issuing01.crlToujours en HTTP (pas HTTPS : boucle de validation) ; LDAP à éviter hors domaine
certificatePoliciesOID de politique (CP/CPS)Publique : 2.23.140.1.2.1 (DV), .2.2 (OV)Obligatoire dans les certificats TLS publics
SCT (1.3.6.1.4.1.11129.2.4.2)Preuves d'inscription Certificate Transparency2 ou 3 SCT embarquésAbsents = rejet par Chrome/Safari pour un certificat public

1.3 Algorithmes et tailles de clés en 2026

UsageRecommandationCommentaire
Racine hors ligneRSA 4096 ou ECDSA P-384, SHA-256/384Durée 15 à 20 ans ; RSA reste le plus compatible (vieux équipements réseau, imprimantes)
AC émettriceRSA 3072/4096 ou ECDSA P-256/P-384Durée 5 à 10 ans, toujours inférieure à la racine
Serveur TLSECDSA P-256 (préféré) ou RSA 2048/3072Double certificat RSA + ECDSA possible sur nginx/Apache/HAProxy
InterditSHA-1, MD5, RSA < 2048OpenSSL 3 au niveau de sécurité par défaut rejette les signatures SHA-1
Post-quantique : l'échange de clés hybride (X25519MLKEM768) est déjà négocié par défaut par les navigateurs récents et OpenSSL 3.5+. Les signatures post-quantiques (ML-DSA) dans les certificats publics ne sont pas encore déployées en 2026 ; pour une PKI interne, l'enjeu immédiat est l'agilité cryptographique : pouvoir réémettre tout le parc rapidement, donc automatiser.

2. Architecture d'une PKI d'entreprise à deux niveaux

2.1 Pourquoi deux niveaux

La clé racine est l'actif le plus critique : sa compromission oblige à redéployer l'ancre de confiance sur tous les postes. On la garde donc hors ligne (VM éteinte, machine physique sans réseau, ou HSM) et on ne l'allume que pour signer une AC émettrice ou publier une CRL. L'AC émettrice, en ligne, signe les certificats du quotidien ; si elle est compromise, on la révoque depuis la racine et on en crée une autre sans toucher aux postes.

                 +-------------------------------+
                 |  ROOT CA (hors ligne)          |   Standalone, pas membre du domaine
                 |  RSA 4096 - 20 ans - CRL 6 mois|   allumée 2x/an (CRL) + renouvellements
                 +---------------+---------------+
                                 | signe (certreq manuel, clé USB / partage temporaire)
                 +---------------v---------------+
                 |  ISSUING CA 01 (Enterprise)    |   membre du domaine, ADCS + modèles
                 |  RSA 4096 - 10 ans - CRL 7 j   |   autoenrollment GPO, OCSP optionnel
                 +---+-----------------------+---+
                     |                       |
        +------------v-----+        +--------v-----------+
        | pki.example.com  |        | Postes, serveurs,  |
        | (HTTP : CRL+AIA) |        | Wi-Fi 802.1X, VPN  |
        +------------------+        +--------------------+

2.2 Choix de conception

QuestionOption recommandéeJustification
Nombre de niveaux2 (racine + émettrice)3 niveaux (racine / politique / émettrice) n'apporte rien hors très grands groupes multi-entités
Durée racine / émettrice / feuille20 ans / 10 ans / 1 an max (interne)Règle : une AC ne peut émettre au-delà de sa propre expiration ; renouveler l'émettrice à mi-vie
Publication CRL/AIAHTTP uniquement, nom DNS dédié (pki.example.com)Indépendant du serveur ADCS : on peut migrer l'AC sans changer les URL gravées dans les certificats
Nom DNS de publicationUn alias stable, jamais le nom d'hôte de l'ACLes URL CDP/AIA sont figées dans chaque certificat émis pendant des années
Haute disponibilitéDeux émettrices indépendantes plutôt qu'un cluster ADCSUn cluster ADCS (failover) est complexe ; deux AC qui publient les mêmes modèles suffisent
Usage TLS publicJamais la PKI interneLes sites exposés utilisent une AC publique (ACME) ; la PKI interne sert aux noms internes, à l'authentification et au chiffrement interne
CPS et documentation : rédigez au minimum une déclaration de pratiques (CPS) interne : qui détient la racine, où sont les sauvegardes de clés, procédure de cérémonie, calendrier de publication CRL, procédure de révocation. Sans elle, la PKI devient ingérable au premier départ de l'administrateur.

3. ADCS : autorité racine hors ligne

3.1 Préparation

  • Windows Server (2022/2025) en groupe de travail, sans carte réseau (ou carte désactivée après mises à jour), disque chiffré.
  • Horloge correcte (pas de NTP : la régler à la main avant chaque session).
  • Le fichier C:\Windows\CAPolicy.inf doit exister avant l'installation du rôle : il est lu une seule fois à l'installation et à chaque renouvellement de l'AC.

3.2 CAPolicy.inf de la racine

[Version]
Signature="$Windows NT$"

[PolicyStatementExtension]
Policies=InternalPolicy

[InternalPolicy]
; OID d'exemple : utilisez un OID sous votre propre arc (PEN IANA)
OID=1.3.6.1.4.1.99999.1.1
Notice="Politique de certification interne Example"
URL=http://pki.example.com/pki/cps.html

[Certsrv_Server]
RenewalKeyLength=4096
RenewalValidityPeriod=Years
RenewalValidityPeriodUnits=20
CRLPeriod=Months
CRLPeriodUnits=6
CRLDeltaPeriodUnits=0
LoadDefaultTemplates=0
AlternateSignatureAlgorithm=0

[BasicConstraintsExtension]
PathLength=1
Critical=Yes
  • CRLDeltaPeriodUnits=0 : pas de delta CRL sur une racine qui émet deux certificats dans sa vie.
  • PathLength=1 : la racine peut signer une AC, qui ne pourra pas en signer d'autres.
  • AlternateSignatureAlgorithm=0 : évite RSASSA-PSS, mal supporté par certains équipements.

3.3 Installation en PowerShell

Install-WindowsFeature ADCS-Cert-Authority -IncludeManagementTools

Install-AdcsCertificationAuthority `
    -CAType StandaloneRootCA `
    -CACommonName "Example Root CA" `
    -CADistinguishedNameSuffix "O=Example,C=FR" `
    -CryptoProviderName "RSA#Microsoft Software Key Storage Provider" `
    -KeyLength 4096 `
    -HashAlgorithmName SHA256 `
    -ValidityPeriod Years -ValidityPeriodUnits 20 `
    -DatabaseDirectory "C:\Windows\System32\CertLog" `
    -Force
Avec un HSM : remplacez le fournisseur par celui du HSM (par exemple le KSP fourni par le constructeur) ; la clé est alors générée et conservée dans le HSM. Voir section 13.

3.4 Paramétrage post-installation : CDP, AIA, durées

# Durée max des certificats signés par la racine (l'AC émettrice)
certutil -setreg CA\ValidityPeriodUnits 10
certutil -setreg CA\ValidityPeriod "Years"

# DN de configuration AD (la racine n'est pas dans le domaine : on le déclare)
certutil -setreg CA\DSConfigDN "CN=Configuration,DC=corp,DC=example,DC=com"

# CDP : fichier local + URL HTTP gravée dans les certificats émis
certutil -setreg CA\CRLPublicationURLs "1:C:\Windows\System32\CertSrv\CertEnroll\%3%8%9.crl\n2:http://pki.example.com/pki/%3%8%9.crl"

# AIA : URL HTTP du certificat de la racine
certutil -setreg CA\CACertPublicationURLs "1:C:\Windows\System32\CertSrv\CertEnroll\%1_%3%4.crt\n2:http://pki.example.com/pki/%1_%3%4.crt"

# CRL tous les 6 mois, recouvrement de 2 semaines
certutil -setreg CA\CRLPeriodUnits 6
certutil -setreg CA\CRLPeriod "Months"
certutil -setreg CA\CRLOverlapUnits 2
certutil -setreg CA\CRLOverlapPeriod "Weeks"

# Audit de toutes les opérations de l'AC
certutil -setreg CA\AuditFilter 127
auditpol /set /subcategory:"Certification Services" /success:enable /failure:enable

Restart-Service certsvc
certutil -crl
VariableSignification
%1Nom DNS du serveur AC
%3Nom court de l'AC (sanitized)
%4Suffixe de renouvellement du certificat d'AC ((1), (2)...)
%8Suffixe de renouvellement de la CRL (nouvelle clé)
%9Suffixe delta CRL (+)

Les préfixes numériques (1:, 2:) sont des masques de bits : 1 = publier le fichier à cet emplacement, 2 = inclure l'URL dans le CDP des certificats émis, etc. On publie localement, et on n'inscrit que l'URL HTTP dans les certificats.

3.5 Exporter vers le domaine

# Sur la racine : récupérer le certificat et la CRL
dir C:\Windows\System32\CertSrv\CertEnroll\

# Sur un serveur membre (Enterprise Admins) : publier dans l'AD
certutil -dspublish -f "Example Root CA.crt" RootCA
certutil -dspublish -f "Example Root CA.crl" ExampleRootCA

# Copier .crt et .crl sur le serveur web pki.example.com
# puis vérifier depuis un poste du domaine :
certutil -verify -urlfetch "Example Root CA.crt"

4. ADCS : autorité émettrice, modèles et autoenrollment

4.1 Serveur de publication HTTP

Un simple IIS (ou nginx/Apache) qui sert un répertoire /pki en HTTP, sans redirection vers HTTPS. Sous IIS, les delta CRL contiennent un + dans le nom : autoriser le double échappement.

New-Item -ItemType Directory C:\pki
New-WebVirtualDirectory -Site "Default Web Site" -Name pki -PhysicalPath C:\pki
& $env:windir\system32\inetsrv\appcmd.exe set config "Default Web Site/pki" `
    -section:system.webServer/security/requestFiltering -allowDoubleEscaping:true
# Types MIME : .crl = application/pkix-crl, .crt = application/pkix-cert (déjà présents par défaut sous IIS)
Pas de HTTPS ni de HSTS sur pki.example.com : pour valider le certificat HTTPS du serveur de CRL, le client devrait télécharger… une CRL. Les clients suivent rarement les redirections pour la révocation. Si un en-tête HSTS includeSubDomains est posé sur example.com, utilisez un nom hors de cette zone ou vérifiez son impact.

4.2 CAPolicy.inf et installation de l'émettrice

[Version]
Signature="$Windows NT$"

[PolicyStatementExtension]
Policies=InternalPolicy

[InternalPolicy]
OID=1.3.6.1.4.1.99999.1.1
URL=http://pki.example.com/pki/cps.html

[Certsrv_Server]
RenewalKeyLength=4096
RenewalValidityPeriod=Years
RenewalValidityPeriodUnits=10
LoadDefaultTemplates=0
AlternateSignatureAlgorithm=0

[BasicConstraintsExtension]
PathLength=0
Critical=Yes
Install-WindowsFeature ADCS-Cert-Authority -IncludeManagementTools

Install-AdcsCertificationAuthority `
    -CAType EnterpriseSubordinateCA `
    -CACommonName "Example Issuing CA 01" `
    -CryptoProviderName "RSA#Microsoft Software Key Storage Provider" `
    -KeyLength 4096 -HashAlgorithmName SHA256 `
    -OutputCertRequestFile C:\pki\issuing01.req -Force

# Transporter issuing01.req sur la racine, puis sur la racine :
certreq -submit -config ".\Example Root CA" C:\transfert\issuing01.req
certutil -resubmit 2           # 2 = RequestId affiché (Standalone : demande en attente)
certreq -retrieve -config ".\Example Root CA" 2 C:\transfert\issuing01.crt

# Retour sur l'émettrice :
certutil -installcert C:\pki\issuing01.crt
Start-Service certsvc
# Paramétrage de l'émettrice
certutil -setreg CA\CRLPublicationURLs "65:C:\Windows\System32\CertSrv\CertEnroll\%3%8%9.crl\n6:http://pki.example.com/pki/%3%8%9.crl\n65:\\pki01.corp.example.com\pki$\%3%8%9.crl"
certutil -setreg CA\CACertPublicationURLs "1:C:\Windows\System32\CertSrv\CertEnroll\%1_%3%4.crt\n2:http://pki.example.com/pki/%1_%3%4.crt"
certutil -setreg CA\CRLPeriodUnits 1
certutil -setreg CA\CRLPeriod "Weeks"
certutil -setreg CA\CRLDeltaPeriodUnits 1
certutil -setreg CA\CRLDeltaPeriod "Days"
certutil -setreg CA\CRLOverlapUnits 12
certutil -setreg CA\CRLOverlapPeriod "Hours"
certutil -setreg CA\ValidityPeriodUnits 2
certutil -setreg CA\ValidityPeriod "Years"
certutil -setreg CA\AuditFilter 127
Restart-Service certsvc
certutil -crl

65 = publier la CRL + publier les delta ; 6 = inscrire l'URL dans le CDP des certificats et dans l'extension IDP des CRL. Vérifiez le résultat avec pkiview.msc (Enterprise PKI) : chaque emplacement doit être « OK ».

4.3 Modèles de certificats

Ne jamais modifier les modèles par défaut : dupliquer (console certtmpl.msc), puis publier sur l'AC (certsrv.msc > Modèles de certificats > Nouveau).

ModèleBaseSujetInscriptionPoints clés
EX-OrdinateurWorkstation AuthenticationConstruit depuis l'AD (DNS)Domain Computers : Read, Enroll, AutoenrollclientAuth seul, 1 an, clé non exportable
EX-ServeurWebWeb ServerFourni dans la requêteGroupe restreint (admins web) + approbation du gestionnaireserverAuth seul ; c'est un modèle ESC1 potentiel : ne pas l'ouvrir à Domain Users
EX-ServeurAutoWeb ServerConstruit depuis l'AD (DNS)Groupe de serveurs : AutoenrollPour les serveurs membres ; SAN = FQDN AD uniquement
EX-UtilisateurUserConstruit depuis l'AD (UPN + email)Domain Users : AutoenrollS/MIME interne, EFS éventuellement ; archivage de clé si chiffrement
EX-DCKerberos AuthenticationADDomain ControllersRemplace « Domain Controller » / « Domain Controller Authentication » (supersede)
EX-RDPWorkstation Authentication modifiéADServeurs RDS : AutoenrollEKU Remote Desktop Authentication (1.3.6.1.4.1.311.54.1.2), GPO « Server authentication certificate template »
# Lister les modèles publiés sur l'AC
certutil -CATemplates
Get-CATemplate

# Publier / retirer un modèle
Add-CATemplate -Name "EX-ServeurAuto" -Force
Remove-CATemplate -Name "WebServer" -Force

4.4 Autoenrollment par GPO

  1. GPO liée au domaine (ou aux OU ciblées) : Configuration ordinateur > Stratégies > Paramètres Windows > Paramètres de sécurité > Stratégies de clé publique > Client des services de certificats - Inscription automatique.
  2. Modèle de configuration : Activé, cocher « Renouveler les certificats expirés, mettre à jour les certificats en attente et supprimer les certificats révoqués » et « Mettre à jour les certificats qui utilisent les modèles de certificats ».
  3. Même paramètre côté Configuration utilisateur pour les certificats utilisateurs.
  4. Sur le modèle : permission Autoenroll (en plus de Read et Enroll) pour le groupe cible.
# Forcer sur un poste et diagnostiquer
gpupdate /force
certutil -pulse
certreq -enroll -machine -q EX-Ordinateur

# Journal : Applications and Services Logs > Microsoft > Windows > CertificateServicesClient-AutoEnrollment
Get-WinEvent -LogName "Microsoft-Windows-CertificateServicesClient-Lifecycle-System/Operational" -MaxEvents 20
Get-ChildItem Cert:\LocalMachine\My | Select-Object Subject, NotAfter, @{n='Template';e={($_.Extensions | Where-Object {$_.Oid.Value -eq '1.3.6.1.4.1.311.21.7'}).Format(0)}}

4.5 Sauvegarde de l'AC

# Base + clé (protégée par mot de passe saisi interactivement)
Backup-CARoleService -Path D:\Backup\CA -Password (Read-Host -AsSecureString)
# Configuration registre (CDP/AIA, périodes)
reg export "HKLM\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration" D:\Backup\CA\certsvc.reg
# Ne pas oublier CAPolicy.inf et la liste des modèles publiés (certutil -CATemplates)

5. Durcissement ADCS : ESC1 à ESC8, Certipy et audit

ADCS est l'un des chemins d'escalade les plus fréquents vers Domain Admin : un certificat d'authentification client permet d'obtenir un TGT Kerberos (PKINIT) au nom de l'identité inscrite dans le certificat, et il reste valide après un changement de mot de passe. La classification ESC (publiée par SpecterOps en 2021, étendue depuis jusqu'à ESC15/ESC16) décrit ces mauvaises configurations. Voir aussi Durcissement Active Directory.

5.1 Tableau des scénarios principaux

ESCCondition vulnérableImpactCorrection
ESC1Modèle avec CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT (« Fournir dans la demande ») + EKU d'authentification client + inscription ouverte à des utilisateurs peu privilégiés + pas d'approbationDemander un certificat avec le SAN/UPN d'un administrateurSujet construit depuis l'AD, ou approbation du gestionnaire, ou inscription restreinte à un groupe d'admins
ESC2Modèle avec EKU Any Purpose ou sans EKUCertificat utilisable pour tout, y compris comme agent d'inscriptionEKU explicites et minimaux
ESC3Modèle Certificate Request Agent ouvertDemander des certificats au nom d'autres utilisateursRestreindre les agents d'inscription (propriétés de l'AC > Agents d'inscription)
ESC4ACL faibles sur un modèle (WriteDACL, WriteOwner, WriteProperty pour Domain Users / Authenticated Users)Rendre un modèle vulnérable ESC1 puis l'exploiterAuditer les ACL des objets pKICertificateTemplate
ESC5ACL faibles sur les objets PKI de l'AD (conteneur Public Key Services, objet AC, NTAuthCertificates) ou sur le serveur ACContrôle de la PKITraiter l'AC comme un actif Tier 0
ESC6Drapeau EDITF_ATTRIBUTESUBJECTALTNAME2 sur l'ACN'importe quel modèle accepte un SAN arbitrairecertutil -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
ESC7Droits ManageCA / ManageCertificates délégués à trop de mondeActiver ESC6, approuver des demandesLimiter aux admins PKI
ESC8Inscription web (/certsrv) ou CES en HTTP/NTLM sans EPARelais NTLM (coercition d'un DC via PetitPotam/PrinterBug) → certificat du DC → DCSyncSupprimer Web Enrollment si inutile ; sinon HTTPS + Extended Protection for Authentication + désactiver NTLM
ESC9 / ESC10Mapping faible des certificats (extension SID absente, StrongCertificateBindingEnforcement < 2)Usurpation via modification d'UPNMode Full Enforcement du mapping fort (KB5014754)
ESC11Interface RPC de l'AC sans chiffrement exigé (IF_ENFORCEENCRYPTICERTREQUEST absent)Relais NTLM vers RPCActiver le drapeau (actif par défaut sur les versions récentes)
ESC13 / ESC15Politique d'émission liée à un groupe (OID group link) ; modèles en schéma v1 acceptant des Application Policies arbitraires (CVE-2024-49019)Élévation de privilègesAppliquer les correctifs, dupliquer les modèles v1 en v2+ et dépublier les v1 inutiles
Mapping fort des certificats (KB5014754) : depuis les mises à jour de 2025, les DC fonctionnent en mode d'application complète : un certificat d'authentification doit contenir l'extension SID (1.3.6.1.4.1.311.25.2), ajoutée automatiquement par une AC Enterprise à jour pour les modèles à sujet construit depuis l'AD, ou être mappé explicitement (altSecurityIdentities au format fort). Les certificats émis hors ADCS (Intune/SCEP, AC tierce) pour l'authentification Windows doivent être vérifiés. Vérifiez l'état exact sur vos DC (événements Kdcsvc 39, 40, 41).

5.2 Auditer avec Certipy (depuis un poste d'audit autorisé)

# Inventaire complet + détection des modèles et AC vulnérables
# (authentification Kerberos avec un ticket existant : pas de mot de passe en ligne de commande)
export KRB5CCNAME=/tmp/audit.ccache
certipy find -k -no-pass -u auditeur@corp.example.com -dc-ip 10.0.0.10 -vulnerable -stdout

# Export JSON/texte pour archivage du rapport
certipy find -k -no-pass -u auditeur@corp.example.com -dc-ip 10.0.0.10 -output audit_adcs_2026-10

Côté Windows, PSPKIAudit / Locksmith (modules PowerShell) produisent un diagnostic similaire et proposent des corrections. BloodHound CE intègre les chemins ADCS (ESC1, ESC3, ESC4, ESC6, ESC9, ESC10, ESC13).

Cadre légal : ces outils sont des outils offensifs. Ne les exécuter que sur votre propre infrastructure, avec un mandat écrit, depuis un poste identifié ; prévenir le SOC (Defender for Identity détecte les requêtes LDAP d'énumération ADCS).

5.3 Contrôles manuels rapides

# ESC6 : le drapeau doit être ABSENT
certutil -getreg policy\EditFlags
# Le retirer s'il est présent
certutil -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
Restart-Service certsvc

# ESC11 : chiffrement des requêtes RPC exigé
certutil -getreg CA\InterfaceFlags      # doit contenir IF_ENFORCEENCRYPTICERTREQUEST

# Modèles où le demandeur fournit le sujet (msPKI-Certificate-Name-Flag bit 1)
Get-ADObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=corp,DC=example,DC=com" `
    -LDAPFilter "(msPKI-Certificate-Name-Flag:1.2.840.113556.1.4.803:=1)" -Properties displayName, pKIExtendedKeyUsage |
    Select-Object displayName, pKIExtendedKeyUsage

# ESC8 : Web Enrollment installé ?
Get-WindowsFeature ADCS-Web-Enrollment, ADCS-Enroll-Web-Svc

5.4 Audit et détection

ÉvénementSignificationPourquoi le surveiller
4886 / 4887Demande reçue / certificat émisComparer le demandeur et le SAN : un utilisateur standard qui obtient un certificat avec l'UPN d'un admin = ESC1
4888Demande refuséeTentatives d'abus
4890 / 4891 / 4892Modification des paramètres / de la configuration / d'une propriété de l'ACActivation d'ESC6, changement d'ACL
4898 / 4899 / 4900Modèle chargé / mis à jour / sécurité modifiéeESC4
4768 (DC)TGT demandé, champ Certificate Information renseignéAuthentification PKINIT inattendue
Tier 0 : les serveurs AC (et le serveur qui héberge l'HSM) ont le même niveau que les contrôleurs de domaine : administration uniquement depuis des postes d'administration dédiés, aucun agent tiers non maîtrisé, sauvegardes chiffrées et isolées. La compromission de la clé d'une AC présente dans NTAuthCertificates permet de forger des certificats d'authentification pour n'importe quel compte (« Golden Certificate »).

6. Alternative open source : step-ca et ACME interne

step-ca (Smallstep, licence Apache 2.0) est une AC en ligne légère, pensée pour l'automatisation : ACME, provisioners OIDC, JWK, X5C, SSH, Kubernetes, et des certificats très courts (24 h par défaut). Idéal pour les environnements Linux, conteneurs et services internes où ADCS n'a pas sa place.

6.1 Comparatif

CritèreADCSstep-caHashiCorp Vault PKI / OpenBao
Intégration Windows / GPONative (autoenrollment, Kerberos PKINIT)NonNon
ACMENon natifOui (HTTP-01, DNS-01, TLS-ALPN-01, device-attest-01)Oui (Vault 1.14+)
Durées courtesPossible mais peu pratiqueConçu pour (heures/jours)Conçu pour
Certificats SSHNonOuiOui
RévocationCRL + OCSPPassive par défaut (durée courte), CRL possibleCRL, OCSP
Cas d'usageParc Windows, 802.1X, smartcardsServices internes, mTLS, conteneursPlateformes déjà sous Vault

6.2 Mise en place (racine hors ligne + step-ca émettrice)

# Initialiser (crée une racine et un intermédiaire ; en prod, importer plutôt
# un intermédiaire signé par votre racine hors ligne)
step ca init --name "Example Internal CA" \
    --dns ca.corp.example.com --address :8443 \
    --provisioner admin@corp.example.com

# Utiliser un intermédiaire existant : remplacer dans $(step path)/certs et secrets
#   intermediate_ca.crt / intermediate_ca_key, puis ajuster ca.json

# Ajouter un provisioner ACME
step ca provisioner add acme --type ACME

# Durées (ca.json, bloc "claims" global ou par provisioner)
#   "claims": { "minTLSCertDuration": "5m", "maxTLSCertDuration": "720h",
#               "defaultTLSCertDuration": "168h" }

# Service systemd
step-ca $(step path)/config/ca.json --password-file /etc/step-ca/password.txt
# Côté client : faire confiance à la racine (empreinte affichée par step ca init)
step ca bootstrap --ca-url https://ca.corp.example.com:8443 --fingerprint <empreinte_sha256_racine> --install

# Certificat via ACME avec certbot
certbot certonly --standalone -d app01.corp.example.com \
    --server https://ca.corp.example.com:8443/acme/acme/directory

# Ou directement avec step, puis renouvellement automatique
step ca certificate app01.corp.example.com app01.crt app01.key
step ca renew --daemon --exec "systemctl reload nginx" app01.crt app01.key
Contraindre les noms : dans ca.json, une politique ("policy": {"x509": {"allow": {"dns": ["*.corp.example.com"]}}}) empêche l'émission pour des noms hors de votre zone, même si un défi ACME réussit. Pour ACME interne, l'AC doit pouvoir résoudre et joindre les noms internes (DNS interne).

7. ACME : défis, wildcard et clients

7.1 Les trois défis

DéfiMécanismeWildcardAvantagesContraintes
HTTP-01Fichier servi sur http://<nom>/.well-known/acme-challenge/<token>, port 80NonLe plus simple, aucun accès DNSPort 80 joignable depuis Internet (et depuis plusieurs points de vue : validation multi-perspective) ; chaque nœud d'un cluster doit servir le jeton
DNS-01Enregistrement TXT _acme-challenge.<nom>OuiServeurs internes non exposés, wildcardNécessite un jeton API DNS : risque majeur s'il permet de modifier toute la zone
TLS-ALPN-01Certificat spécial présenté sur 443 avec ALPN acme-tls/1NonSeul le 443 est ouvertSupporté par peu de clients (Caddy, Traefik, lego)
Déléguer le DNS-01 : plutôt que de donner un jeton sur toute la zone example.com, créez un CNAME _acme-challenge.www.example.com → www.acme.example.net pointant vers une zone dédiée (ou un serveur acme-dns), et ne donnez au client ACME que les droits sur cette zone. Les clients certbot, acme.sh et lego suivent le CNAME.

7.2 Clients ACME

ClientPlateformePoints forts
certbotLinuxRéférence EFF, plugins nginx/apache, plugins DNS (certbot-dns-*), hooks deploy
acme.shShell POSIXAucune dépendance, >150 API DNS, mode délégation ; CA par défaut = ZeroSSL : forcer Let's Encrypt si voulu
legoBinaire GoMultiplateforme, nombreux fournisseurs DNS, TLS-ALPN-01
win-acme (wacs.exe)WindowsIntégration IIS, magasin Windows, RDS, Exchange, tâche planifiée
Posh-ACMEPowerShellScriptable, nombreux plugins DNS
Caddy, Traefik, cert-managerServeur / proxy / KubernetesACME intégré, renouvellement transparent (voir Kubernetes)

7.3 Exemples

# certbot, wildcard via DNS-01 (plugin Cloudflare, jeton dans un fichier 600)
certbot certonly --dns-cloudflare \
    --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
    -d example.com -d '*.example.com' \
    --key-type ecdsa --elliptic-curve secp256r1 \
    --deploy-hook "systemctl reload nginx"

# acme.sh : forcer Let's Encrypt, puis wildcard en DNS-01
acme.sh --set-default-ca --server letsencrypt
acme.sh --issue --dns dns_cf -d example.com -d '*.example.com' --keylength ec-256
acme.sh --install-cert -d example.com --ecc \
    --key-file /etc/ssl/private/example.com.key \
    --fullchain-file /etc/ssl/certs/example.com.fullchain.pem \
    --reloadcmd "systemctl reload nginx"

# lego, DNS-01 (identifiants via variables d'environnement du fournisseur)
lego --email ops@example.com --dns cloudflare -d example.com -d '*.example.com' --key-type ec256 run
lego --email ops@example.com --dns cloudflare -d example.com -d '*.example.com' renew --days 30

# win-acme, mode non interactif pour un site IIS
wacs.exe --source iis --siteid 1 --installation iis --emailaddress ops@example.com --accepttos

7.4 Bonnes pratiques ACME

  • Tester sur l'environnement staging de l'AC avant la production (limites de débit).
  • Renouveler à environ 1/3 de la durée restante ; mieux : utiliser ARI (ACME Renewal Information, RFC 9773) quand le client le supporte, pour que l'AC indique la fenêtre de renouvellement (et la raccourcisse en cas de révocation de masse).
  • Un compte ACME par usage/serveur, clé de compte protégée (elle permet de révoquer).
  • Recharger le service après renouvellement (deploy hook) : un certificat renouvelé sur disque mais pas rechargé expire quand même en mémoire.
  • Verrouiller l'émission par CAA avec accounturi (section 14).

8. Réduction des durées de vie et automatisation

8.1 Calendrier CA/B Forum (ballot SC-081)

Adopté en 2025, le ballot SC-081 réduit progressivement la durée maximale des certificats TLS publics et la durée de réutilisation des validations :

À partir duDurée max. du certificatRéutilisation de la validation de domaine (DCV)
Avant le 15 mars 2026398 jours398 jours
15 mars 2026200 jours200 jours
15 mars 2027100 jours100 jours
15 mars 202947 jours10 jours

La réutilisation des informations d'identité de l'organisation (OV/EV) est également ramenée à 398 jours. Ces règles ne concernent pas les PKI internes, mais tout service exposé avec un certificat public y est soumis, y compris les certificats achetés « pour un an » : l'AC les réémet alors en plusieurs fois.

8.2 Autres changements récents de l'écosystème

  • Let's Encrypt a abandonné OCSP en 2025 (URL OCSP retirées des certificats, répondeurs arrêtés) au profit des CRL ; il propose des profils dont un à durée très courte (environ 6 jours) et a annoncé une réduction progressive de sa durée standard (90 jours vers 45 jours). Vérifiez le calendrier officiel avant de dimensionner vos fenêtres de renouvellement.
  • EKU clientAuth : le programme racine de Chrome exige que les hiérarchies TLS publiques soient dédiées à l'authentification serveur ; les AC publiques retirent donc l'EKU clientAuth de leurs certificats TLS (2025-2026). Conséquence : un certificat public ne peut plus servir de certificat client mTLS (connecteurs SMTP serveur-à-serveur, fédérations, VPN). Pour ces usages, utiliser une PKI privée dédiée.
  • Distrust : les navigateurs retirent régulièrement la confiance à des AC (Entrust en 2024 pour les certificats émis après une date butoir, par exemple). Une PKI automatisée permet de changer d'AC en quelques heures.

8.3 Ce que cela impose

AvantAprès
Renouvellement manuel annuel, CSR envoyée par mailRenouvellement entièrement automatique (ACME, API de l'AC commerciale, cert-manager)
Certificat copié à la main sur load balancer, pare-feu, applianceDistribution par API (Ansible, Terraform, API du boîtier) ou terminaison TLS centralisée
Wildcard partagé sur 40 serveursUn certificat par service, clés distinctes, rotation indépendante
Inventaire ExcelInventaire généré (scan réseau + CT logs + magasins) et alertes
Validation DCV « une fois pour un an »DCV automatisable (enregistrement DNS persistant via CNAME délégué, ou HTTP-01 à chaque émission)
Repérer les points non automatisables dès maintenant : appliances (imprimantes, iDRAC/iLO, NAS, équipements réseau), applications Java avec keystore, clients qui épinglent un certificat (pinning). Soit on les place derrière un reverse proxy, soit on leur donne un certificat de la PKI interne (durée libre), soit on scripte leur API. Voir Ansible et CI/CD.

9. Inventaire et supervision d'expiration

9.1 Sources d'inventaire

  • Base de l'AC interne : certutil -view (ADCS) ou base step-ca.
  • CT logs pour les certificats publics : tous les certificats émis pour vos domaines, y compris ceux que vous ignorez (shadow IT).
  • Scan réseau des ports TLS (443, 8443, 636, 993, 995, 465, 587 STARTTLS, 3389, 5986...).
  • Magasins locaux : Windows (Cert:\), fichiers PEM, keystores Java.
# ADCS : certificats émis expirant dans les 30 jours
certutil -view -restrict "NotAfter<=now+30:00,NotAfter>=now,Disposition=20" `
    -out "RequestID,RequesterName,CommonName,CertificateTemplate,NotAfter" csv > expirants.csv

9.2 Script bash : vérification d'une liste d'hôtes

#!/usr/bin/env bash
# check_certs.sh - usage : ./check_certs.sh hosts.txt 30
# hosts.txt : une ligne "nom:port" (ex. www.example.com:443)
set -u
LIST="$1"; DAYS="${2:-30}"; RC=0
while IFS=: read -r HOST PORT; do
    [ -z "$HOST" ] && continue
    PORT="${PORT:-443}"
    PEM=$(timeout 10 openssl s_client -connect "$HOST:$PORT" -servername "$HOST" \
          -verify_return_error </dev/null 2>/dev/null | openssl x509 2>/dev/null)
    if [ -z "$PEM" ]; then
        echo "CRIT $HOST:$PORT injoignable ou chaine invalide"; RC=2; continue
    fi
    END=$(echo "$PEM" | openssl x509 -noout -enddate | cut -d= -f2)
    if ! echo "$PEM" | openssl x509 -noout -checkend $((DAYS*86400)) >/dev/null; then
        echo "WARN $HOST:$PORT expire le $END"; [ $RC -lt 1 ] && RC=1
    else
        echo "OK   $HOST:$PORT expire le $END"
    fi
done < "$LIST"
exit $RC

9.3 Script PowerShell : magasins Windows du parc

# Certificats machine expirant sous 30 jours sur une liste de serveurs
$serveurs = Get-Content .\serveurs.txt
Invoke-Command -ComputerName $serveurs -ScriptBlock {
    Get-ChildItem Cert:\LocalMachine\My |
        Where-Object { $_.NotAfter -lt (Get-Date).AddDays(30) } |
        Select-Object @{n='Serveur';e={$env:COMPUTERNAME}}, Subject,
            @{n='SAN';e={($_.Extensions | Where-Object {$_.Oid.FriendlyName -eq 'Subject Alternative Name'}).Format(0)}},
            Issuer, NotAfter, Thumbprint, HasPrivateKey
} | Sort-Object NotAfter | Export-Csv .\certs_expirants.csv -NoTypeInformation -Encoding UTF8

# Certificat lié à un site IIS / un écouteur HTTP.sys
netsh http show sslcert

9.4 Prometheus blackbox_exporter

# blackbox.yml
modules:
  https_2xx:
    prober: http
    timeout: 10s
    http:
      method: GET
      fail_if_not_ssl: true
      preferred_ip_protocol: ip4

# règle d'alerte
groups:
  - name: tls
    rules:
      - alert: CertificatExpireBientot
        expr: (probe_ssl_earliest_cert_expiry - time()) / 86400 < 21
        for: 1h
        labels: { severity: warning }
        annotations:
          summary: "Certificat de {{ $labels.instance }} expire dans {{ $value | humanize }} jours"
      - alert: CertificatExpireCritique
        expr: (probe_ssl_earliest_cert_expiry - time()) / 86400 < 7
        labels: { severity: critical }

probe_ssl_earliest_cert_expiry prend l'expiration la plus proche de toute la chaîne présentée, ce qui détecte aussi un intermédiaire qui expire. Pour des fichiers locaux, x509-certificate-exporter surveille PEM, kubeconfig et secrets Kubernetes.

9.5 Zabbix

Zabbix agent 2 fournit la clé web.certificate.get[<hôte>,<port>,<adresse>] et le modèle officiel Website certificate by Zabbix agent 2 : éléments dépendants (date d'expiration, émetteur, statut de validation) et déclencheurs paramétrables par macro ({$CERT.EXPIRY.WARN}). Pour les protocoles STARTTLS, utiliser un external check basé sur le script de la section 9.2 avec -starttls.

Seuils conseillés avec des certificats courts : si le renouvellement automatique se fait à J-30 pour un certificat de 90 jours, une alerte à J-21 signifie que l'automatisation a échoué depuis 9 jours. Alertez sur l'échec du renouvellement (code retour du client ACME, logs) plutôt que sur l'expiration seule. L'outil SSL Checker du site permet un contrôle ponctuel.

10. Révocation : CRL, OCSP, stapling

MécanismePrincipeAvantagesInconvénients
CRLListe signée des numéros de série révoqués, publiée périodiquementSimple, cachable, aucune fuite de vie privéeTaille, latence jusqu'à la prochaine publication
Delta CRLUniquement les révocations depuis la dernière CRL de baseFraîcheur sans gros téléchargementsSupport inégal hors Windows
OCSPRequête en ligne sur un numéro de sérieRéponse fraîcheFuite de vie privée (l'AC voit les sites visités), point de défaillance, soft-fail
OCSP staplingLe serveur joint la réponse OCSP à la négociation TLSPas de requête client vers l'ACSans objet si l'AC n'a plus d'OCSP
CRLSets / CRLiteListes agrégées poussées par Chrome / FirefoxRapide, privéPropre aux navigateurs, pas aux API/outils
Durée courteCertificat de quelques jours, pas de révocationAucune infrastructure de révocationExige une automatisation sans faille

10.1 Conséquences pratiques en 2026

  • Avec Let's Encrypt, ssl_stapling on; (nginx) ou SSLUseStapling On (Apache) ne sert plus à rien et peut générer des avertissements dans les logs : à retirer. Certaines AC commerciales maintiennent OCSP ; le stapling reste alors pertinent.
  • Must-Staple (extension TLS Feature) est à proscrire : il casse le site si l'AC arrête OCSP.
  • En interne, la révocation est effective pour Windows (CryptoAPI vérifie CRL/OCSP par défaut pour l'authentification), pour 802.1X (NPS vérifie la CRL : CRL expirée = Wi-Fi coupé pour tout le monde) et pour les VPN qui l'activent.
CRL expirée = panne : un client strict qui ne peut pas obtenir une CRL valide refuse le certificat. Supervisez la date Next Update de chaque CRL publiée (y compris celle de la racine hors ligne, à republier tous les 6 mois). Exemple de contrôle :
# Prochaine mise à jour d'une CRL publiée
curl -s http://pki.example.com/pki/ExampleIssuingCA01.crl | openssl crl -inform DER -noout -lastupdate -nextupdate

# Windows : télécharger et vérifier toute la chaîne (CDP, AIA, OCSP)
certutil -verify -urlfetch .\serveur.cer
certutil -URL .\serveur.cer           # interface graphique de test des URL

# Vider le cache d'URL CryptoAPI après une republication
certutil -urlcache * delete
certutil -setreg chain\ChainCacheResyncFiletime @now

10.2 Répondeur OCSP ADCS (Online Responder)

  • Rôle ADCS-Online-Cert, modèle OCSP Response Signing (avec id-pkix-ocsp-nocheck), configuration de révocation pointant vers la CRL de l'émettrice.
  • Ajouter l'URL OCSP dans l'AIA de l'émettrice : certutil -setreg CA\CACertPublicationURLs "...\n32:http://ocsp.example.com/ocsp" (32 = inclure dans l'extension OCSP), puis redémarrer.
  • Seuls les certificats émis après la modification contiennent l'URL OCSP.

11. mTLS, certificats clients et 802.1X

11.1 Principe

En TLS mutuel, le serveur envoie un CertificateRequest listant les AC acceptées ; le client présente un certificat avec EKU clientAuth et prouve la possession de la clé. Le serveur doit valider la chaîne et autoriser l'identité (sujet/SAN), sinon tout porteur d'un certificat de la même AC passe.

11.2 nginx

server {
    listen 443 ssl;
    server_name api.example.com;
    ssl_certificate         /etc/ssl/certs/api.fullchain.pem;
    ssl_certificate_key     /etc/ssl/private/api.key;

    # AC acceptees pour les certificats clients (PKI privee DEDIEE)
    ssl_client_certificate  /etc/ssl/clients/client-ca-chain.pem;
    ssl_verify_client       on;
    ssl_verify_depth        2;
    ssl_crl                 /etc/ssl/clients/client-ca.crl;   # a rafraichir par cron

    location / {
        # Autorisation : n'accepter qu'une liste de sujets
        if ($ssl_client_s_dn !~ "CN=(svc-facturation|svc-crm)\.corp\.example\.com") { return 403; }
        proxy_set_header X-Client-DN $ssl_client_s_dn;
        proxy_pass http://127.0.0.1:8080;
    }
}
# Apache
SSLVerifyClient require
SSLVerifyDepth 2
SSLCACertificateFile /etc/ssl/clients/client-ca-chain.pem
SSLCARevocationFile  /etc/ssl/clients/client-ca.crl
SSLCARevocationCheck chain
<Location />
    Require expr %{SSL_CLIENT_S_DN_CN} in {'svc-facturation.corp.example.com', 'svc-crm.corp.example.com'}
</Location>

# Test client
curl --cert client.crt --key client.key https://api.example.com/health
Ne jamais faire confiance à une AC publique pour l'authentification client : n'importe qui peut obtenir un certificat de cette AC. Utilisez une AC privée dédiée (ou un intermédiaire dédié) pour les clients. Et derrière un reverse proxy, le backend ne doit jamais accepter un en-tête X-Client-DN venant d'ailleurs que du proxy.

11.3 802.1X (EAP-TLS) : Wi-Fi et filaire

  • Serveur RADIUS (NPS ou FreeRADIUS) : certificat serveur avec EKU serverAuth issu de la PKI interne ; les clients doivent être configurés pour valider ce certificat (AC de confiance + nom du serveur), sinon un faux point d'accès capture les échanges.
  • Postes : certificat ordinateur (autoenrollment) ou utilisateur ; profils Wi-Fi par GPO ou Intune (voir Intune : profils SCEP/PKCS, ou Microsoft Cloud PKI).
  • Mapping fort : NPS s'appuie sur l'AD ; les certificats sans extension SID ou mapping fort sont refusés en mode d'application complète (KB5014754). Pour Intune SCEP, inclure l'URI SID dans le SAN selon la documentation Microsoft.
  • CRL : NPS vérifie la révocation ; la publication de CRL devient un service critique.
# FreeRADIUS (mods-available/eap), extrait
eap {
    default_eap_type = tls
    tls-config tls-common {
        private_key_file = ${certdir}/radius.key
        certificate_file = ${certdir}/radius.pem
        ca_file          = ${cadir}/client-ca-chain.pem
        check_crl        = yes
        ca_path          = ${cadir}
        tls_min_version  = "1.2"
        check_cert_cn    = %{User-Name}
    }
    tls { tls = tls-common }
}

Pour le VPN, voir OpenVPN et pfSense (AC interne du pare-feu ou import de l'AC d'entreprise).

12. Signature de code et S/MIME

12.1 Signature de code

  • Certificat public (logiciel distribué hors de l'entreprise) : depuis 2023, les exigences de base CA/B Forum imposent que la clé de signature de code soit générée et conservée dans un matériel certifié (HSM, jeton FIPS 140-2 niveau 2 ou équivalent, ou service de signature cloud). Plus de fichier PFX téléchargeable.
  • Certificat interne (scripts PowerShell, macros, packages internes) : modèle ADCS Code Signing restreint à un groupe, clé non exportable, et AC déployée dans Trusted Publishers par GPO (voir Sécurité PowerShell).
  • Horodatage obligatoire (RFC 3161) : sans horodatage, la signature devient invalide à l'expiration du certificat ; avec, elle reste valide.
# Windows : signer un exécutable (certificat dans le magasin, sélection par empreinte)
signtool sign /sha1 <empreinte> /fd SHA256 /tr <URL_TSA_de_votre_AC> /td SHA256 .\outil.exe
signtool verify /pa /v .\outil.exe

# PowerShell : signer un script
$cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1
Set-AuthenticodeSignature -FilePath .\deploy.ps1 -Certificate $cert -TimestampServer <URL_TSA_de_votre_AC> -HashAlgorithm SHA256
Get-AuthenticodeSignature .\deploy.ps1 | Format-List

# Linux : signature détachée avec cosign / sigstore pour les artefacts et images
cosign sign-blob --key cosign.key --output-signature app.sig app.tar.gz

12.2 S/MIME

  • Les certificats S/MIME publics sont régis depuis 2023 par les S/MIME Baseline Requirements du CA/B Forum (profils mailbox, organization, sponsored, individual ; profils legacy progressivement abandonnés).
  • Distinguer signature (clé non archivée) et chiffrement (clé archivée : Key Recovery Agent dans ADCS), sinon les messages chiffrés deviennent illisibles après perte de la clé ou départ de l'utilisateur.
  • Dans Exchange Online, la distribution des certificats publics passe par la GAL (attribut userSMIMECertificate) ; voir Microsoft 365 / Exchange.
# Archivage de clé : inscrire un certificat Key Recovery Agent, puis le déclarer
# dans les propriétés de l'AC (onglet "Agents de récupération")
# Le modèle de chiffrement doit cocher "Archiver la clé privée du sujet"
# Récupération :
certutil -getkey <numéro_de_série> blob.out
certutil -recoverkey blob.out recup.pfx

13. HSM et protection des clés privées

StockageProtectionUsage typiqueRemarques
Fichier PEM/PFXPermissions + chiffrement par mot de passeServeurs web, conteneursAcceptable pour des clés courtes et automatisées ; jamais dans un dépôt Git
Magasin Windows, clé non exportableDPAPI (logicielle)Serveurs, postes« Non exportable » se contourne avec des droits admin (mimikatz) : ce n'est pas une barrière forte
TPMMatérielle, liée à la machinePostes (Microsoft Platform Crypto Provider), attestationClé réellement non extractible ; idéal pour les certificats machine/Wi-Fi
Carte à puce / YubiKey (PIV)Matérielle, PINComptes d'admin, signature de code interneAuthentification forte des administrateurs
HSM réseau / PCIeFIPS 140-2/140-3 niveau 3, quorum (M parmi N)Clés d'ACCoûteux, mais exigé pour une AC critique
HSM USB (type YubiHSM 2)MatérielleRacine hors ligne de petite PKIBon compromis coût / sécurité
HSM cloud (Azure Managed HSM, AWS CloudHSM, Cloud KMS)FIPS 140-3 niveau 3 selon offreAC en ligne cloud, signatureVoir Azure ; attention à la réversibilité (clés non exportables)

13.1 Cérémonie de clé (racine)

  1. Script écrit et relu à l'avance, liste des participants (opérateur, témoin, détenteurs de parts).
  2. Machine dédiée, sans réseau, OS installé depuis un média vérifié (empreinte).
  3. Génération de la clé dans l'HSM ; sauvegarde de la clé (wrappée) sur deux supports, stockés dans deux lieux.
  4. Signature de l'intermédiaire, première CRL, export des certificats publics.
  5. Procès-verbal signé, empreintes SHA-256 du certificat racine consignées, scellés.
# Interagir avec un HSM PKCS#11 depuis OpenSSL 3 (provider pkcs11)
openssl req -new -provider pkcs11 -provider default \
    -key "pkcs11:token=CA;object=issuing01;type=private" \
    -subj "/CN=Example Issuing CA 02" -out issuing02.csr

# Lister les objets d'un jeton
pkcs11-tool --module /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so --list-objects --login
Sauvegarde : une clé d'AC sans sauvegarde testée est une PKI à durée de vie limitée à celle du matériel. Testez la restauration (sur un HSM de secours ou dans un environnement isolé) au moins une fois. Voir Stratégie de sauvegarde.

14. Certificate Transparency et CAA

14.1 Certificate Transparency

  • Tout certificat TLS public doit être inscrit dans des journaux CT publics et append-only ; Chrome et Safari exigent des SCT (preuves d'inscription).
  • Surveillance : abonnez-vous aux notifications d'un service de monitoring CT, ou interrogez périodiquement un moteur de recherche CT (crt.sh, par exemple) pour détecter tout certificat émis à votre insu.
  • Fuite d'information : chaque nom inscrit dans un certificat public devient public (vpn-paris.example.com, jenkins-preprod.example.com). Pour les noms internes, utiliser la PKI interne ou un wildcard ; ne pas considérer un nom comme secret.
  • L'écosystème CT migre vers des journaux à API « statique » (tuiles), sans impact pour les clients finaux.
# Lister les certificats connus pour un domaine via l'API JSON de crt.sh
curl -s "https://crt.sh/?q=%25.example.com&output=json" | \
    jq -r '.[] | [.not_before, .issuer_name, .name_value] | @tsv' | sort -u | tail -50

14.2 CAA (RFC 8659)

L'enregistrement DNS CAA liste les AC autorisées à émettre pour un domaine ; toute AC publique doit le vérifier avant émission. Les extensions RFC 8657 permettent de restreindre à un compte ACME et à des méthodes de validation.

example.com.  3600 IN CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/<id_compte>; validationmethods=dns-01"
example.com.  3600 IN CAA 0 issuewild "letsencrypt.org; validationmethods=dns-01"
example.com.  3600 IN CAA 0 iodef "mailto:securite@example.com"

# Vérifier
dig +short CAA example.com
Resolve-DnsName example.com -Type CAA
  • issuewild ";" interdit tout wildcard.
  • Le CAA est hérité en remontant l'arbre DNS, mais un CNAME est suivi : un sous-domaine qui pointe vers un SaaS peut hériter du CAA du SaaS.
  • Oublier une AC utilisée par un fournisseur (CDN, hébergeur de messagerie) bloque ses renouvellements : inventorier avant de publier.

Voir aussi SSL Labs (section CAA).

15. Dépannage

SymptômeCause probableDiagnosticCorrection
OK dans le navigateur, unable to get local issuer certificate dans curl / Java / PythonChaîne incomplète : le serveur n'envoie que la feuille (le navigateur complète via AIA ou cache)openssl s_client -connect h:443 -servername h -showcerts : un seul certificatConfigurer le fullchain (feuille + intermédiaires)
Erreur sur les anciens clients uniquementMauvais intermédiaire (ancienne chaîne, cross-sign expiré) ou racine absente des vieux magasinsComparer AKI de la feuille et SKI de l'intermédiaire envoyéServir l'intermédiaire fourni avec le certificat, mettre à jour les magasins
certificate is not yet valid / has expired alors que le certificat est neufHorloge du client ou du serveur fausse (VM restaurée, NTP bloqué, RTC)date -u, w32tm /query /statusCorriger NTP ; les certificats ACME sont souvent antidatés d'une heure, mais pas plus
NET::ERR_CERT_COMMON_NAME_INVALID, Hostname mismatchNom absent du SAN (souvent l'apex ou www), ou accès par IPopenssl x509 -noout -ext subjectAltNameRéémettre avec tous les noms ; un wildcard ne couvre qu'un niveau et pas l'apex
Le service ne démarre pas : key values mismatchClé ne correspondant pas au certificat (renouvellement avec nouvelle clé, mauvais fichier)Comparer les empreintes des clés publiques (voir OpenSSL)Remettre la bonne paire
Windows : certificat sans clé privée après importImport du .cer seul, ou certificat récupéré sur une autre machine que celle de la CSRcertutil -store my : « Aucun fournisseur de clé »certutil -repairstore my <numéro_de_série> sur la machine d'origine, ou import du PFX
Autoenrollment sans effetPermission Autoenroll manquante, modèle non publié, GPO non appliquée, Supersede mal configuréJournal CertificateServicesClient-AutoEnrollment, gpresult /hCorriger ACL / publication, certutil -pulse
Échec de validation sur tous les postes du domaine à date fixeCRL (souvent celle de la racine hors ligne) expiréecertutil -verify -urlfetch : « CRL expirée » ; pkiview.mscAllumer la racine, certutil -crl, publier ; superviser NextUpdate
Erreur 404 sur la delta CRL (IIS)Le + du nom de fichier est refuséLogs IIS : 404.11allowDoubleEscaping=true sur le répertoire virtuel
Renouvellement ACME en échec : CAA record prevents issuanceCAA ne contient pas l'AC ou le comptedig CAA sur le nom et ses parentsAjouter l'AC / corriger accounturi
ACME HTTP-01 : Timeout during connectPort 80 fermé, redirection vers un autre hôte, IPv6 (AAAA) non serviTester depuis l'extérieur en IPv4 et IPv6Ouvrir 80, corriger AAAA, ou passer en DNS-01
Wi-Fi 802.1X refusé après mise à jour des DCMapping fort : certificat sans SIDÉvénements Kdcsvc 39/41, logs NPS (raison 16, 22...)Réémettre depuis un modèle à jour, ou mapping explicite fort
Java : PKIX path building failedAC interne absente du truststore Java (indépendant du magasin OS)keytool -list -cacertskeytool -importcert -cacerts -alias example-root -file root.crt (ou truststore applicatif)

15.1 Commandes de diagnostic essentielles

# Chaîne envoyée et vérification
openssl s_client -connect www.example.com:443 -servername www.example.com -showcerts </dev/null
# Sujet / émetteur / dates / SAN
openssl x509 -in cert.pem -noout -subject -issuer -dates -ext subjectAltName
# Chaîne locale
openssl verify -CAfile root.pem -untrusted intermediate.pem cert.pem
# Windows
certutil -verify -urlfetch cert.cer
certutil -dump cert.cer

L'outil Cipher Suite du site aide à interpréter les suites négociées ; pour la configuration serveur, voir Apache.

16. Checklist de production

16.1 PKI interne

  • ☐ Racine hors ligne (ou HSM), sauvegarde de la clé testée, CPS rédigée.
  • ☐ CDP/AIA en HTTP sur un alias DNS stable, testés avec certutil -verify -urlfetch depuis un poste ET depuis un serveur Linux.
  • ☐ Calendrier de publication de la CRL racine (rappel à J-30 du NextUpdate) et supervision automatique de toutes les CRL.
  • ☐ Modèles dupliqués, EKU minimaux, aucun modèle « sujet fourni » ouvert aux utilisateurs, modèles inutiles dépubliés.
  • ☐ EDITF_ATTRIBUTESUBJECTALTNAME2 absent, Web Enrollment supprimé ou protégé (HTTPS + EPA), droits ManageCA restreints.
  • ☐ Audit Certipy/Locksmith sans ESC ouvert, rejoué après chaque modification de modèle.
  • ☐ Audit ADCS activé (AuditFilter 127), événements 4886/4887/4899/4900 remontés au SIEM.
  • ☐ Serveurs AC traités en Tier 0 ; mapping fort des certificats en mode d'application complète.
  • ☐ Sauvegarde ADCS (base, clé, registre, CAPolicy.inf) et procédure de restauration documentée.

16.2 Certificats publics

  • ☐ Renouvellement 100 % automatique, compatible avec 47 jours (ARI si possible), rechargement du service inclus.
  • ☐ Alerte sur l'échec du renouvellement ET sur l'expiration (J-21 / J-7) de toute la chaîne.
  • ☐ Fullchain servie, racine non servie, clé ECDSA P-256 ou RSA ≥ 2048.
  • ☐ CAA avec accounturi et validationmethods, iodef renseigné.
  • ☐ Surveillance CT des domaines de l'organisation.
  • ☐ Stapling désactivé si l'AC n'a plus d'OCSP, aucun Must-Staple.
  • ☐ Aucun usage d'un certificat TLS public pour l'authentification client (EKU clientAuth retiré).
  • ☐ Jetons API DNS limités à une zone de délégation _acme-challenge.
  • ☐ Inventaire généré (scan + CT + magasins), propriétaire identifié pour chaque certificat.
  • ☐ Note A/A+ vérifiée (SSL Labs) et audit global (Audit de sécurité).