Contrat de fournisseur KMS
HsmSignerInterface est le contrat public qu’un tiers implémente pour fournir la garde des clés à NextPDF. Ton code détient la clé privée. Le moteur, lui, construit la structure CMS.
Installation
Section intitulée « Installation »composer require nextpdf/core:^3Vue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »NextPDF sépare l’assemblage de la signature de la garde des clés. Le moteur prépare la plage d’octets et assemble la structure CMS SignedData. Il ne détient pas la clé privée. La garde des clés est déléguée à un back end de signature via un contrat public.
Tu implémentes l’un des trois contrats publics :
SignerInterface. Contrat de base. Il renvoie unSignatureResultpour les données fournies. Il applique un horodatage. Il indique si la validation à long terme est prise en charge. Utilise ce contrat lorsque la logique de signature s’exécute dans le processus.HsmSignerInterface. Contrat de garde des clés. L’implémentation doit effectuer l’opération de signature à l’intérieur de la frontière matérielle. La clé privée ne doit pas quitter cette frontière. Un fournisseur de système de gestion de clés implémente ce contrat.DeferredSignerInterface. Extension deSignerInterfacepour les back ends asynchrones. L’appelant soumet les données, reçoit un identifiant de tâche, puis récupère le résultat plus tard.
Cette page spécifie le contrat public. Elle ne décrit aucune implémentation interne de NextPDF Pro ni de NextPDF Enterprise. Une édition payante peut fournir une implémentation prise en charge de ce contrat. Tu dépends du contrat, pas de l’implémentation.
Exigence de garde des clés
Section intitulée « Exigence de garde des clés »Le contrat exige que la clé privée ne quitte jamais la frontière sécurisée. Les pratiques établies vont dans le même sens. NIST SP 800-57 Part 1 Revision 5 définit la gestion des clés comme la prise en charge d’une clé pendant tout son cycle de vie. Ce cycle couvre, de manière sécurisée, la génération, le stockage, la distribution, l’utilisation et la destruction. PKCS#11 v3.1 rend cette frontière effective. Lorsqu’un objet de clé privée définit CKA_SENSITIVE à true ou CKA_EXTRACTABLE à false, le jeton ne doit pas révéler la valeur de la clé en clair en dehors du jeton.
Ton implémentation doit respecter cette exigence. Le moteur ne peut pas l’imposer à ta place. Si ta méthode sign() peut lire les octets bruts de la clé dans la mémoire du processus, la propriété de sécurité du contrat est perdue.
Surface d’API
Section intitulée « Surface d’API »NextPDF\Contracts\HsmSignerInterface (stable, depuis 1.0.0) :
| Méthode | Renvoie | Objectif |
|---|---|---|
sign(string $data, string $algorithm) | string | Signe les données à l’intérieur de la frontière matérielle. Renvoie les octets bruts de la signature. Lève RuntimeException en cas d’échec. |
getCertificateDer() | string | Renvoie le certificat X.509 du signataire au format DER. |
getCertificateChainDer() | array<string> | Renvoie les certificats intermédiaires, de l’émetteur jusqu’à la racine, en excluant le certificat du signataire. |
getPublicKeyAlgorithm() | string | Renvoie l’identifiant de l’algorithme de clé publique. |
NextPDF\Contracts\SignerInterface (stable, depuis 1.0.0) :
| Méthode | Renvoie | Objectif |
|---|---|---|
sign(string $data) | SignatureResult | Renvoie la structure CMS SignedData encodée en DER. |
timestamp(string $signatureValue) | string | Renvoie un jeton d’horodatage RFC 3161 encodé en DER. |
supportsLtv() | bool | Indique si les données de validation à long terme peuvent être intégrées. |
NextPDF\Contracts\DeferredSignerInterface (expérimental, depuis 3.0.0) étend SignerInterface en ajoutant submitForSigning(), retrieveSignature() et isComplete() pour les back ends asynchrones.
Les niveaux de signature produits par le moteur suivent les profils PAdES. ETSI EN 319 142-2 définit des profils PAdES étendus qui s’appuient sur les blocs de construction de base de EN 319 142-1. Le moteur associe les niveaux B-B, B-T, B-LT et B-LTA à ces blocs de construction. Ton signataire fournit l’opération cryptographique et le matériel de certificat nécessaires au moteur.
Exemple de code — Démarrage rapide
Section intitulée « Exemple de code — Démarrage rapide »Voici un fournisseur minimal de type PKCS#11. L’appel de signature est délégué au jeton. La valeur de la clé n’est jamais lue dans PHP.
<?php
declare(strict_types=1);
use NextPDF\Contracts\HsmSignerInterface;
final class TokenSigner implements HsmSignerInterface{ public function __construct(private readonly TokenSession $session) {}
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): string { // The token computes the signature. The key stays inside the token. return $this->session->c_sign($data, $algorithm); }
public function getCertificateDer(): string { return $this->session->readCertificate(); }
/** @return array<string> */ public function getCertificateChainDer(): array { return $this->session->readChain(); }
public function getPublicKeyAlgorithm(): string { return 'rsaEncryption'; }}Exemple de code — Production
Section intitulée « Exemple de code — Production »Un fournisseur de production valide les entrées, échoue en mode fermé en cas d’erreur du jeton et ne journalise jamais le matériel de clé ni de signature.
<?php
declare(strict_types=1);
use NextPDF\Contracts\HsmSignerInterface;use Psr\Log\LoggerInterface;use RuntimeException;
final class KmsSigner implements HsmSignerInterface{ public function __construct( private readonly RemoteKmsClient $kms, private readonly string $keyId, private readonly LoggerInterface $logger, ) {}
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): string { if ($data === '') { throw new RuntimeException('Refusing to sign empty data'); }
try { // The KMS performs the operation. The key never reaches this process. return $this->kms->sign($this->keyId, $data, $algorithm); } catch (\Throwable $error) { // Fail closed. Do not log key material or signature bytes. $this->logger->error('kms.sign.failed', ['key' => $this->keyId]);
throw new RuntimeException('KMS signing failed', previous: $error); } }
public function getCertificateDer(): string { return $this->kms->certificate($this->keyId); }
/** @return array<string> */ public function getCertificateChainDer(): array { return $this->kms->chain($this->keyId); }
public function getPublicKeyAlgorithm(): string { return $this->kms->algorithm($this->keyId); }}Cas limites et pièges
Section intitulée « Cas limites et pièges »- Format des octets de signature. Renvoie les octets bruts de la signature. Pour RSA, les octets sont au format DER. Pour ECDSA, les octets sont la valeur brute
r, puis la valeurs. - Ordre de la chaîne.
getCertificateChainDer()exclut le certificat du signataire. Ordonne les intermédiaires depuis l’émetteur jusqu’à la racine. - Identifiants d’algorithme.
sign()utilise des identifiants de style OpenSSL.getPublicKeyAlgorithm()renvoie le nom de l’algorithme X.509. - L’échec est en mode fermé. Lève
RuntimeExceptionpour toute erreur du jeton ou du KMS. Ne renvoie ni signature partielle ni signature vide. - Destruction des clés. Lorsqu’une clé atteint la fin de sa cryptopériode, détruis-la conformément à ta procédure de gestion des clés. NIST SP 800-57 Part 1 Revision 5 §8.2.1.2 indique qu’une clé doit être détruite dès qu’elle n’est plus nécessaire. La destruction elle-même suit le §8.3.4.
Résidence des données et mesures d’atténuation des données personnelles
Section intitulée « Résidence des données et mesures d’atténuation des données personnelles »Le contrat ne transfère que les données à signer et le matériel de certificat. Il ne transfère ni le contenu du document ni les données personnelles au back end de signature. Garde la plage d’octets au minimum. Ne place aucune donnée personnelle dans les champs de motif ou d’emplacement de signature. Ces champs sont observables dans le fichier signé.
Télémétrie sûre et nettoyage des journaux
Section intitulée « Télémétrie sûre et nettoyage des journaux »Ne journalise jamais les données transmises à sign(), les octets de signature renvoyés, l’identifiant de clé sous une forme récupérable, ni aucun composant privé de certificat. Journalise uniquement le résultat de l’opération et une référence non réversible. Le hook SignatureAppliedEvent constitue l’ancre d’audit prise en charge. Consulte Déclencheurs d’action.
Modèle de menace
Section intitulée « Modèle de menace »| Actif | Menace | Atténuation |
|---|---|---|
| Clé privée | Fuite dans la mémoire du processus | Le contrat exige que la signature ait lieu dans la frontière ; PKCS#11 CKA_SENSITIVE / CKA_EXTRACTABLE imposent la non-extractabilité |
| Oracle de signature | Requêtes de signature non bornées | L’implémentation limite le débit et authentifie les appelants |
| Chaîne de certificats | Substitution | L’implémentation renvoie une chaîne qui remonte jusqu’à une racine de confiance |
| Octets de signature | Divulgation par les journaux | Le chemin d’erreur échoue en mode fermé ; aucun matériel de signature n’est présent dans la télémétrie |
| Clé au-delà de la cryptopériode | Utilisation continue | Destruction des clés conformément à NIST SP 800-57 Part 1 Revision 5 §8.2.1.2 |
Conformité
Section intitulée « Conformité »Les niveaux de signature sont conformes aux profils PAdES. ETSI EN 319 142-2 §5.1 définit des profils PAdES étendus à partir des blocs de construction de base de EN 319 142-1. Le moteur assemble ces blocs de construction à partir du matériel fourni par ton signataire. La gestion des clés s’aligne sur le cycle de vie de NIST SP 800-57 Part 1 Revision 5, y compris l’exigence de destruction du §8.2.1.2. La garde matérielle des clés s’aligne sur les attributs de clé non extractible de PKCS#11 v3.1. Les citations sont consignées dans l’en-tête de la page.
Contrôle des exportations et gouvernance de la revue
Section intitulée « Contrôle des exportations et gouvernance de la revue »Cette page couvre la garde des clés via PKCS#11 et par module de sécurité matériel, donc son en-tête définit export_control_class: legal-review-required. Selon la politique de revue de la documentation (plan §17, porte 6), toute page comportant un mode de sécurité, un chemin ou un contenu correspondant à PAdES, FIPS, HSM ou PKCS#11 exige la validation de l’équipe GitHub @nextpdf-labs/crypto-reviewers avant de pouvoir être publiée. Cette approbation CODEOWNERS constitue une porte de fusion stricte : la page reste publish: false jusqu’à ce que la revue légale de contrôle des exportations et la revue @nextpdf-labs/crypto-reviewers soient toutes deux terminées.
Contexte commercial
Section intitulée « Contexte commercial »NextPDF Enterprise fournit une implémentation prise en charge de ce contrat, avec garde des clés par système de gestion de clés, assemblage de chaîne de certificats et intégration d’audit. Soit tu implémentes HsmSignerInterface toi-même dans le cœur, soit tu consommes l’implémentation Enterprise via le même contrat public sans changement de code.
Voir aussi
Section intitulée « Voir aussi »- Vue d’ensemble de la création d’extensions
- Règles de stabilité du SPI
- Déclencheurs d’action et écouteurs d’événements
Contrats et modules associés
Section intitulée « Contrats et modules associés »- Référence des contrats de signature —
SignerInterface,HsmSignerInterface,DeferredSignerInterfaceet le fournisseur d’horodatage. - Référence du contrat de politique de sécurité — surface SPI sensible à la sécurité, du même groupe.
- Règles de stabilité du SPI — la promesse d’interface qui sous-tend les contrats de signature
stable. - Déclencheurs d’action et écouteurs d’événements —
SignatureAppliedEvent, l’ancre d’audit prise en charge. - Vue d’ensemble de la création d’extensions — la surface SPI publique complète.
Le glossaire définit key management system, cryptoperiod et HSM ; consulte le glossaire publié pour leurs définitions canoniques.