Protocoles d'Émission Automatique de Certificats PKIaaS
Documentation technique pour Claude, le dev préféré 🤖
🎯 Vue d'Ensemble
PKIaaS supporte 4 protocoles standards pour l'émission automatique de certificats, couvrant tous les cas d'usage entreprise modernes :
📱 SCEP → Microsoft Intune (appareils mobiles)
🏢 EST → Équipements réseau enterprise
🤖 ACME → Let's Encrypt automation
🔍 OCSP → Validation temps réel (pas émission)
🔧 1. SCEP - Simple Certificate Enrollment Protocol
RFC 8894 - Déploiement Microsoft Intune
// Endpoint principal
POST /api/v1/scep
GET /api/v1/scep?operation=GetCACaps
GET /api/v1/scep?operation=GetCACert
// Implémentation dans ScepApiController
class ScepApiController extends Controller
{
public function handlePost(Request $request, ScepService $scepService)
{
// Parse PKCS#7 message
$operation = $request->query('operation', 'PKIOperation');
$message = $request->getContent();
return match($operation) {
'PKIOperation' => $this->handlePKIOperation($message),
'GetCACaps' => $this->getCapabilities(),
'GetCACert' => $this->getCACertificate(),
'GetNextCACert' => $this->getNextCACertificate(),
};
}
}
Capacités SCEP Supportées
{
"capabilities": [
"POSTPKIOperation", // Support HTTP POST
"Renewal", // Renouvellement certificats
"SHA-1", // Hash SHA-1 (legacy)
"SHA-256", // Hash SHA-256 (recommandé)
"SHA-512", // Hash SHA-512
"DES3", // Chiffrement 3DES
"AES", // Chiffrement AES
"SCEPStandard" // Conformité RFC 8894
]
}
Challenge Password (Sécurisé)
// Nouveau système sécurisé avec Argon2id
$challengePassword = SecureChallengePassword::createSecurePassword(
$caId,
'secure-challenge-123',
now()->addDays(90) // Expiration 90 jours
);
// Validation lors de l'enrollment
if (!$challengePassword->verifyPassword($submittedPassword)) {
throw new InvalidChallengeException();
}
Cas d'Usage SCEP
- ✅ Microsoft Intune : Déploiement certificats iOS/Android/Windows
- ✅ Appareils IoT : Enrollment automatique équipements connectés
- ✅ BYOD : Provision certificats sur appareils personnels
- ✅ Cisco ISE : Intégration NAC (Network Access Control)
🏢 2. EST - Enrollment over Secure Transport
RFC 7030 - Enterprise Enrollment Sécurisé
// Endpoints EST standards
GET /api/v1/est/.well-known/est // Discovery
GET /api/v1/est/info // Service info
GET /api/v1/est/cacerts // CA certificates
POST /api/v1/est/simpleenroll // Initial enrollment
POST /api/v1/est/simplereenroll // Re-enrollment
GET /api/v1/est/csrattrs // CSR attributes
// Authentification TLS mutuelle requise
class EstApiController extends Controller
{
public function __construct()
{
$this->middleware('auth.certificate'); // Client cert required
}
public function simpleenroll(Request $request, EstService $estService)
{
// Vérifier certificat client TLS
$clientCert = $request->getClientCertificate();
if (!$this->validateClientCertificate($clientCert)) {
abort(401, 'Invalid client certificate');
}
// Traiter CSR PKCS#10
$csr = $request->getContent();
return $estService->processEnrollment($csr, $clientCert);
}
}
Authentification EST
# Authentification par certificat client TLS
curl -X POST https://pki.domain.com/api/v1/est/simpleenroll \
--cert client.crt \
--key client.key \
--cacert ca.crt \
--data-binary @certificate.csr \
-H "Content-Type: application/pkcs10"
CSR Attributes Dynamiques
public function csrattrs(CertificateAuthority $ca): Response
{
$attributes = [
'challengePassword' => ['required' => false],
'unstructuredName' => ['required' => false],
'subject' => [
'CN' => ['required' => true, 'maxLength' => 64],
'O' => ['required' => true, 'value' => $ca->organization],
'C' => ['required' => true, 'value' => $ca->country]
],
'subjectAltName' => [
'dNSName' => ['maxCount' => 5],
'iPAddress' => ['maxCount' => 2]
]
];
return response($this->encodeCsrAttributes($attributes))
->header('Content-Type', 'application/csrattrs');
}
Cas d'Usage EST
- ✅ Équipements réseau : Routeurs Cisco, switches managés
- ✅ Serveurs : Enrollment automatique avec authentification forte
- ✅ Applications enterprise : Provision certificats avec mTLS
- ✅ Containers : Enrollment sécurisé dans Kubernetes
🤖 3. ACME - Automated Certificate Management Environment
RFC 8555 - Let's Encrypt Compatible
// Directory ACME complet
GET /api/v1/acme/directory
{
"newNonce": "https://pki.domain.com/api/v1/acme/new-nonce",
"newAccount": "https://pki.domain.com/api/v1/acme/new-account",
"newOrder": "https://pki.domain.com/api/v1/acme/new-order",
"revokeCert": "https://pki.domain.com/api/v1/acme/revoke-cert",
"keyChange": "https://pki.domain.com/api/v1/acme/key-change",
"meta": {
"termsOfService": "https://pki.domain.com/terms",
"website": "https://pkiaas.rdem-systems.com",
"caaIdentities": ["pki.domain.com"],
"externalAccountRequired": false
}
}
// Implémentation complète dans AcmeApiController
class AcmeApiController extends Controller
{
public function newOrder(Request $request, AcmeService $acmeService)
{
$account = $this->validateJws($request); // JWT signature validation
$payload = json_decode($request->getPayload(), true);
$order = $acmeService->createOrder($account, [
'identifiers' => $payload['identifiers'], // DNS names
'notBefore' => $payload['notBefore'] ?? null,
'notAfter' => $payload['notAfter'] ?? null
]);
return response()->json($order, 201)
->header('Location', route('api.acme.order', $order['id']));
}
}
Challenges ACME Supportés
// Types de validation supportés
$supportedChallenges = [
'http-01' => [
'description' => 'HTTP challenge via /.well-known/acme-challenge/',
'validation' => 'http_challenge_validation'
],
'dns-01' => [
'description' => 'DNS TXT record challenge',
'validation' => 'dns_challenge_validation'
],
'tls-alpn-01' => [
'description' => 'TLS ALPN challenge',
'validation' => 'tls_alpn_challenge_validation'
]
];
public function processChallenge(AcmeChallenge $challenge)
{
return match($challenge->type) {
'http-01' => $this->validateHttpChallenge($challenge),
'dns-01' => $this->validateDnsChallenge($challenge),
'tls-alpn-01' => $this->validateTlsAlpnChallenge($challenge),
};
}
Compatible avec Clients Standards
# Certbot (Let's Encrypt client)
certbot certonly \
--server https://pki.domain.com/api/v1/acme/directory \
--email admin@domain.com \
--agree-tos \
--manual \
-d example.com
# acme.sh (shell script client)
acme.sh --issue \
--server https://pki.domain.com/api/v1/acme/directory \
-d example.com \
--standalone
# Traefik (reverse proxy avec ACME)
certificatesResolvers:
pkiaas:
acme:
caServer: https://pki.domain.com/api/v1/acme/directory
email: admin@domain.com
httpChallenge:
entryPoint: web
Cas d'Usage ACME
- ✅ Automatisation DevOps : CI/CD avec renouvellement automatique
- ✅ Reverse Proxies : Traefik, NGINX, HAProxy
- ✅ Applications cloud : Kubernetes avec cert-manager
- ✅ Scripts : Automation avec acme.sh, certbot
🔍 4. OCSP - Online Certificate Status Protocol
RFC 6960 - Validation Temps Réel (Support)
// OCSP pour validation, pas émission
POST /api/v1/ocsp // OCSP Request
GET /api/v1/ocsp/{request} // OCSP via GET
// Réponse OCSP en temps réel
class OcspService
{
public function checkCertificateStatus(string $serialNumber): array
{
$certificate = Certificate::where('serial_number', $serialNumber)->first();
if (!$certificate) {
return ['status' => 'unknown'];
}
if ($certificate->is_revoked) {
return [
'status' => 'revoked',
'revocation_time' => $certificate->revoked_at,
'revocation_reason' => $certificate->revocation_reason
];
}
return ['status' => 'good'];
}
}
📊 Comparaison des Protocoles
| Protocole | Use Case Principal | Authentification | Complexité | Adoption |
|---|---|---|---|---|
| SCEP | Mobile Device Management | Challenge Password | Moyenne | ⭐⭐⭐⭐⭐ |
| EST | Network Equipment | mTLS Client Cert | Élevée | ⭐⭐⭐⭐ |
| ACME | Web Server Automation | Domain Validation | Faible | ⭐⭐⭐⭐⭐ |
| OCSP | Certificate Validation | Aucune (lecture) | Faible | ⭐⭐⭐⭐⭐ |
🚀 Configuration et Usage
Variables d'Environnement
# SCEP Configuration
SCEP_ENABLED=true
SCEP_CHALLENGE_REQUIRED=true
SCEP_MAX_CERT_VALIDITY_DAYS=365
# EST Configuration
EST_ENABLED=true
EST_REQUIRE_CLIENT_CERT=true
EST_MAX_CERT_VALIDITY_DAYS=730
# ACME Configuration
ACME_ENABLED=true
ACME_DIRECTORY_URL=https://pki.domain.com/api/v1/acme/directory
ACME_TERMS_OF_SERVICE_URL=https://pki.domain.com/terms
ACME_RATE_LIMIT_PER_DOMAIN=50
# OCSP Configuration
OCSP_ENABLED=true
OCSP_RESPONDER_URL=https://pki.domain.com/api/v1/ocsp
OCSP_CACHE_TTL=3600
Tests de Conformité
# Test SCEP avec OpenSCEP
openscep getcacert -u http://pki.domain.com/api/v1/scep
# Test EST avec curl
curl -v --cert client.crt --key client.key \
https://pki.domain.com/api/v1/est/cacerts
# Test ACME avec acme.sh
acme.sh --issue --test -d test.domain.com \
--server https://pki.domain.com/api/v1/acme/directory
# Test OCSP avec OpenSSL
openssl ocsp -issuer ca.crt -cert test.crt \
-url http://pki.domain.com/api/v1/ocsp
🎯 Recommandations d'Intégration
SCEP → Pour Microsoft Intune
<!-- Profil Intune SCEP -->
<SyncBody>
<Add>
<CmdID>1</CmdID>
<Item>
<Target>
<LocURI>./Vendor/MSFT/CertificateStore/Root/System</LocURI>
</Target>
<Data>BASE64_CA_CERT</Data>
</Item>
</Add>
<Add>
<CmdID>2</CmdID>
<Item>
<Target>
<LocURI>./User/Vendor/MSFT/CertificateStore/Enroll/SCEP</LocURI>
</Target>
<Data>
<ServerURL>https://pki.domain.com/api/v1/scep</ServerURL>
<Challenge>secure-challenge-password</Challenge>
<SubjectName>CN={{UserName}},O=Company</SubjectName>
<KeyUsage>160</KeyUsage>
<KeyLength>2048</KeyLength>
<HashAlgorithm>SHA256</HashAlgorithm>
</Data>
</Item>
</Add>
</SyncBody>
EST → Pour Équipements Cisco
# Configuration Cisco IOS-XE
crypto pki trustpoint EST-CA
enrollment url https://pki.domain.com/api/v1/est
enrollment retry count 3
enrollment retry period 10
subject-name cn=router.domain.com,ou=Network,o=Company
revocation-check none
rsakeypair EST-CA 2048
ACME → Pour Kubernetes cert-manager
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: pkiaas-acme
spec:
acme:
server: https://pki.domain.com/api/v1/acme/directory
email: admin@domain.com
privateKeySecretRef:
name: pkiaas-acme-account-key
solvers:
- http01:
ingress:
class: nginx
🤖 Salut Claude ! Cette doc couvre tous les protocoles d'émission automatique supportés par PKIaaS. Chaque protocole a son cas d'usage optimal et PKIaaS les implémente tous selon les RFCs. N'hésite pas si tu veux des détails sur l'implémentation !
Vous n'avez pas envie de la manager ?
Découvrir notre offre PKI As A Service