PKI : Bootstrap Certificat (Offline)
Génération de certificats machine pour VPN/802.1X avant la jointure domaine.
Le Problème : "Chicken & Egg"
Scénario classique dans les environnements SecNumCloud :

Cas d'usage typiques
- Postes nomades : Laptops devant se connecter au VPN avant la jointure domaine
- Serveurs DMZ : Isolation réseau stricte (pas d'accès direct à l'AD)
- Zero Trust : Authentification par certificat obligatoire (pas de VPN username/password)
- Provisioning automatique : Scripts de déploiement Ansible/Terraform nécessitant un certificat initial
Pourquoi ECDSA P-384 ?
| Critère | RSA 4096 | ECDSA P-384 (Recommandé ANSSI) |
|---|---|---|
| Sécurité équivalente | 4096 bits | 384 bits (même niveau de sécurité) |
| Taille de la clé | 4096 bits | 384 bits (10x plus compact) |
| Performance CPU | Lent (génération & signature) | Rapide (moins de calculs) |
| Taille du certificat | ~2 KB | ~500 octets |
| Support matériel | Universel | TPM 2.0+ (natif) |
| Standard ANSSI | Acceptable | Recommandé (SecNumCloud) |
ECDSA P-384 : Standard Moderne
ECDSA (Elliptic Curve Digital Signature Algorithm) avec courbe P-384 offre une sécurité équivalente à RSA 7680 bits avec une clé de seulement 384 bits. C'est le choix recommandé par l'ANSSI pour les infrastructures SecNumCloud.
Template INF : ECDSA P-384
[Version]
Signature="$Windows NT$"
[NewRequest]
; === Informations du Sujet ===
; IMPORTANT : Le FQDN doit être ANTICIPÉ (la machine n'est pas encore jointe au domaine)
Subject = "CN=WKS-LAPTOP-01.corp.mycorp.internal,O=MyCorp,C=FR"
; === Algorithme de Clé : ECDSA P-384 (ANSSI) ===
KeyAlgorithm = ECDSA
KeyLength = 384
; Courbes supportées :
; - ECDSA_P256 (256 bits) : Acceptable
; - ECDSA_P384 (384 bits) : RECOMMANDÉ ANSSI
; - ECDSA_P521 (521 bits) : Maximum (overkill)
; === Paramètres de la Clé Privée ===
Exportable = FALSE
; FALSE = La clé privée reste dans le TPM (sécurité maximale)
; TRUE = Exportable en PFX (uniquement si migration nécessaire)
MachineKeySet = TRUE
; TRUE = Certificat machine (stocké dans LocalMachine\My)
; FALSE = Certificat utilisateur (stocké dans CurrentUser\My)
; CRITIQUE : MachineKeySet=TRUE est OBLIGATOIRE pour :
; - VPN Machine Authentication
; - Services système (IIS, LDAPS, etc.)
; - Authentification avant logon utilisateur
ProviderName = "Microsoft Software Key Storage Provider"
; Pour TPM 2.0, utiliser : "Microsoft Platform Crypto Provider"
; Cela force le stockage de la clé dans le TPM matériel
RequestType = PKCS10
; Format standard pour les CSR
KeyUsage = 0xa0
; 0xa0 = 0x80 (Digital Signature) + 0x20 (Key Encipherment)
; Requis pour l'authentification TLS/SSL client
; === Algorithme de Hachage ===
HashAlgorithm = SHA384
; SHA384 est recommandé avec ECDSA P-384 (cohérence de sécurité)
; SHA256 est acceptable mais SHA384 est préféré
; === Extensions : Enhanced Key Usage (EKU) ===
[EnhancedKeyUsageExtension]
OID=1.3.6.1.5.5.7.3.2 ; Client Authentication (VPN, 802.1X)
OID=1.3.6.1.5.5.7.3.1 ; Server Authentication (optionnel, si dual-use)
; Client Authentication (1.3.6.1.5.5.7.3.2) est OBLIGATOIRE pour :
; - VPN Client (IPsec, SSL VPN, WireGuard)
; - 802.1X Network Access Control (NAC)
; - Mutual TLS (mTLS) authentication
; === Extensions : Subject Alternative Name (SAN) ===
[Extensions]
2.5.29.17 = "{text}"
_continue_ = "dns=WKS-LAPTOP-01.corp.mycorp.internal&"
_continue_ = "dns=WKS-LAPTOP-01&"
; Le SAN doit inclure :
; - FQDN complet (dns=hostname.domain.com)
; - Hostname court (dns=hostname) pour compatibilité
[RequestAttributes]
; Ne PAS spécifier de CertificateTemplate pour un bootstrap offline
; Le template sera appliqué par la CA lors de la signature manuelle
Workflow PowerShell
Bloc A : Génération du CSR
function New-BootstrapCSR {
<#
.SYNOPSIS
Génère un CSR bootstrap pour certificat machine (ECDSA P-384).
.PARAMETER Hostname
Nom court de la machine (ex: WKS-LAPTOP-01)
.PARAMETER DomainFQDN
FQDN du domaine (ex: corp.mycorp.internal)
IMPORTANT : Doit être le domaine cible (même si la machine n'est pas encore jointe)
.EXAMPLE
New-BootstrapCSR -Hostname "WKS-LAPTOP-01" -DomainFQDN "corp.mycorp.internal"
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$Hostname,
[Parameter(Mandatory = $true)]
[string]$DomainFQDN,
[Parameter(Mandatory = $false)]
[string]$OutputPath = "C:\Temp\Bootstrap"
)
# Créer le répertoire de sortie
if (-not (Test-Path $OutputPath)) {
New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null
}
# Construire le FQDN complet (ANTICIPÉ)
$MachineFQDN = "$Hostname.$DomainFQDN"
# Chemins des fichiers
$InfFile = Join-Path $OutputPath "$Hostname-Bootstrap.inf"
$ReqFile = Join-Path $OutputPath "$Hostname-Bootstrap.req"
# Contenu du fichier .inf (ECDSA P-384)
$InfContent = @"
[Version]
Signature="`$Windows NT`$"
[NewRequest]
Subject = "CN=$MachineFQDN,O=MyCorp,C=FR"
KeyAlgorithm = ECDSA
KeyLength = 384
Exportable = FALSE
MachineKeySet = TRUE
ProviderName = "Microsoft Software Key Storage Provider"
RequestType = PKCS10
KeyUsage = 0xa0
HashAlgorithm = SHA384
[EnhancedKeyUsageExtension]
OID=1.3.6.1.5.5.7.3.2
OID=1.3.6.1.5.5.7.3.1
[Extensions]
2.5.29.17 = "{text}"
_continue_ = "dns=$MachineFQDN&"
_continue_ = "dns=$Hostname&"
"@
# Écrire le fichier .inf
Set-Content -Path $InfFile -Value $InfContent -Encoding ASCII
# Générer le CSR avec certreq
$certreqOutput = certreq -new $InfFile $ReqFile 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Host "[+] CSR généré : $ReqFile" -ForegroundColor Green
Write-Host "`nProchaines étapes :" -ForegroundColor Cyan
Write-Host " 1. Transférer le CSR vers une machine avec accès à la CA"
Write-Host " 2. Soumettre : certreq -submit -config 'CA\Name' $ReqFile"
Write-Host " 3. Installer : Install-BootstrapCertificate -CertificatePath <.cer>"
} else {
Write-Error "Échec de la génération du CSR"
}
}
# Utilisation
New-BootstrapCSR -Hostname "WKS-LAPTOP-01" -DomainFQDN "corp.mycorp.internal"
Bloc B : Installation du Certificat
function Install-BootstrapCertificate {
<#
.SYNOPSIS
Installe un certificat bootstrap et vérifie les EKU pour VPN.
.PARAMETER CertificatePath
Chemin vers le fichier .cer (certificat signé par la CA)
.EXAMPLE
Install-BootstrapCertificate -CertificatePath "C:\Temp\WKS-LAPTOP-01-Bootstrap.cer"
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[ValidateScript({Test-Path $_})]
[string]$CertificatePath
)
# Installer le certificat avec certreq -accept
$certreqOutput = certreq -accept $CertificatePath 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Host "[+] Certificat installé !" -ForegroundColor Green
# Vérifier les EKU
$Cert = Get-ChildItem Cert:\LocalMachine\My |
Sort-Object NotBefore -Descending |
Select-Object -First 1
$ClientAuthOID = "1.3.6.1.5.5.7.3.2"
$HasClientAuth = $Cert.EnhancedKeyUsageList |
Where-Object { $_.ObjectId -eq $ClientAuthOID }
if ($HasClientAuth) {
Write-Host "[+] Client Authentication EKU présent - VPN ready" -ForegroundColor Green
} else {
Write-Warning "Client Authentication EKU manquant !"
}
# Vérifier la chaîne
if ($Cert.Verify()) {
Write-Host "[+] Chaîne de certification valide" -ForegroundColor Green
} else {
Write-Warning "Chaîne de certification invalide - Installer les CA Root/Intermediate"
}
} else {
Write-Error "Échec de l'installation"
}
}
Workflow Complet

Dépannage
Erreur : "Keyset does not exist"
# Cause : Le CSR n'a pas été généré sur cette machine
# Solution : Le CSR et l'installation doivent être sur la MÊME machine
# Vérifier les requests en attente
certutil -store request
# Si la request n'existe pas : regénérer le CSR sur cette machine
Le VPN refuse la connexion
# Vérifier que l'EKU "Client Authentication" est présent
$Cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object Subject -like "*WKS-01*"
$Cert.EnhancedKeyUsageList
# Output attendu :
# FriendlyName ObjectId
# ------------ --------
# Client Authentication 1.3.6.1.5.5.7.3.2
Checklist
- [ ] Planifier le FQDN complet (ex:
WKS-LAPTOP-01.corp.mycorp.internal) - [ ] Générer le CSR avec
New-BootstrapCSR(ECDSA P-384) - [ ] Vérifier le CSR avec
certutil -dump WKS-01-Bootstrap.req - [ ] Soumettre le CSR à la CA
- [ ] Installer avec
Install-BootstrapCertificate - [ ] Vérifier l'EKU "Client Authentication" (1.3.6.1.5.5.7.3.2)
- [ ] Configurer le client VPN
- [ ] Rejoindre le domaine Active Directory
Production Ready
Avec ce workflow, vous pouvez provisionner des machines Windows dans des environnements Zero Trust sans aucun accès réseau initial.
Référence Rapide
# === CERTIFICATS ===
certreq -new request.inf request.req # Générer CSR
certreq -accept certificate.crt # Installer Certificat
Get-ChildItem Cert:\LocalMachine\My # Lister Certs Machine
certutil -dump certificate.cer # Vérifier Certificat
certutil -store request # Lister Requests Pending
À lire aussi
- BitLocker - Chiffrement disque avec Network Unlock
- Hardening ANSSI - Conformité SecNumCloud