Enterprise édition
Signature par module matériel de sécurité (PKCS#11)
NextPDF Enterprise signe un PDF avec une clé détenue à l’intérieur d’un module matériel de sécurité (HSM). Tu pointes le signataire vers un jeton PKCS#11 — une carte à puce, un jeton Universal Serial Bus (USB) ou un HSM en réseau — et l’opération de signature s’exécute sur l’appareil. La clé privée ne quitte jamais la frontière du jeton. Cette page se situe au niveau du comportement : elle énonce ce que fait le signataire, ce que tu fournis, et où la garde des clés cesse d’être la responsabilité de NextPDF.
Le signataire HSM se résout via le contrat de signataire du Core, de sorte que ton application dépend du contrat, et non du type Enterprise concret. Il étend le même chemin de signature Cryptographic Message Syntax (CMS) que le Core utilise, sauf que l’opération cryptographique est déléguée au jeton.
Les prérequis sont énoncés dans le frontmatter et répétés sous Prérequis afin que tu ne sois pas pris au dépourvu en cours de tâche.
Disponibilité et licence
Section intitulée « Disponibilité et licence »Cette capacité est livrée dans NextPDF Enterprise (nextpdf/enterprise) et s’active avec une enveloppe de licence de niveau Enterprise. Un déploiement sans ce droit ne charge pas les classes de la capacité. Compare les éditions et obtiens une licence.
NextPDF Core livre un signataire CMS logiciel qui détient la clé en mémoire (in-process) ou en accepte une via le contrat de stratégie de signature du Core ; NextPDF Pro ajoute des stratégies de signature distantes et cloud key-management-service (KMS). La garde matérielle des clés via PKCS#11 est une capacité Enterprise, non fournie par le Core ni par Pro.
Ce que fait cette capacité
Section intitulée « Ce que fait cette capacité »Un jeton PKCS#11 expose des objets cryptographiques — certificats et clés privées — derrière une bibliothèque partagée du fournisseur. Le signataire Enterprise adapte cette bibliothèque :
- Il ouvre la bibliothèque partagée du jeton une fois par processus et met en cache la poignée du module, car PKCS#11 exige que le module soit initialisé exactement une fois par processus.
- Il ouvre une session sur le slot configuré et se connecte avec le PIN fourni. La connexion authentifie l’utilisateur avant toute opération sur clé privée, conformément à PKCS#11 v3.1 §5.6.8.
- Il localise le certificat de signature sur le jeton par étiquette, lit le certificat sous forme Distinguished Encoding Rules (DER) et détecte l’algorithme de la clé publique.
- Au moment de la signature, il localise la clé privée par étiquette — qui peut différer de l’étiquette du certificat sur certains jetons — et demande au jeton de calculer la signature. Les données à signer sont transmises ; la clé reste sur l’appareil.
Le signataire prend en charge RSA avec un remplissage PKCS#1 v1.5 (SHA-256, SHA-384, SHA-512), RSA avec un remplissage Probabilistic Signature Scheme (PSS) où la longueur du sel est égale à la longueur de l’empreinte, et Elliptic Curve Digital Signature Algorithm (ECDSA) avec SHA-256, SHA-384 et SHA-512. La courbe ECDSA et l’empreinte sont appariées de manière conventionnelle — P-256 avec SHA-256, P-384 avec SHA-384, P-521 avec SHA-512 — selon l’appariement recommandé dans RFC 5480. Un jeton renvoie une signature ECDSA sous forme de concaténation brute des deux entiers ; le signataire la convertit dans la forme encodée en DER que PDF et OpenSSL attendent.
Pour la génération de signature, une clé RSA d’au moins 2048 bits et un ordre de courbe ECDSA d’au moins 224 bits sont les minimums acceptables conformément à NIST SP 800-131A Rev.2 §3. Approvisionne la clé de ton jeton à ces tailles ou au-delà.
Un chemin alternatif par moteur OpenSSL existe pour les jetons adossés à un moteur. Sur OpenSSL 3.x, l’extension OpenSSL de PHP n’expose pas l’interface de programmation d’application (API) de moteur, de sorte que la classe de moteur est dépréciée ; la voie adossée à un moteur prise en charge exécute le binaire en ligne de commande d’OpenSSL. Préfère le chemin direct PKCS#11 lorsque ton jeton dispose d’une bibliothèque PKCS#11.
Pourquoi ça fonctionne ainsi
Section intitulée « Pourquoi ça fonctionne ainsi »La décision structurante est que la clé privée ne quitte jamais le jeton. Le signataire délègue donc l’opération cryptographique à l’appareil et ne fait transiter que les données à signer à travers la jointure PKCS#11. Il ne lit ni ne reconstruit jamais de matériel de clé dans la mémoire de PHP. Il se résout via le contrat HsmSignerInterface du Core plutôt que via un type Enterprise concret, de sorte que le code de signature est identique que la clé réside dans un logiciel, un KMS cloud ou un jeton matériel. Il met en cache la poignée du module une fois par processus parce que PKCS#11 initialise chaque module exactement une fois par processus, puis convertit la sortie ECDSA brute du jeton en DER afin que les validateurs voient l’encodage qu’ils attendent. C’est la garde, et non la commodité, qui dicte la forme : la frontière de confiance reste au bord de l’appareil.
Contexte de conception : Signature adossée à un HSM.
Prérequis
Section intitulée « Prérequis »Avant de signer avec un HSM, confirme chaque élément :
- Installe NextPDF Core et le paquet Enterprise :
composer require nextpdf/core:^3etcomposer require nextpdf/enterprise. - Détiens une licence NextPDF Enterprise active ; résous le paquet avec tes identifiants de licence sur Private Packagist.
- Installe la bibliothèque partagée PKCS#11 du fournisseur du jeton sur l’hôte (par exemple un
.sosous Linux ou un.dllsous Windows) et note son chemin absolu, le numéro de slot et les étiquettes d’objets. - Charge l’extension PHP
ext-pkcs11. Elle n’est pas fournie avec PHP standard et doit être installée séparément. Le constructeur du signataire lève une erreur d’opération typée lorsque l’extension est absente.
Configuration
Section intitulée « Configuration »Fournis ces entrées au signataire :
- Chemin de la bibliothèque — le chemin absolu vers la bibliothèque partagée PKCS#11 du fournisseur.
- Identifiant de slot — le numéro de slot du jeton, typiquement
0. - PIN — le PIN du jeton. Traite-le comme un secret : fournis-le depuis ton gestionnaire de secrets, jamais depuis le code source ni les journaux. Le signataire marque le paramètre PIN comme sensible afin qu’il soit exclu des traces de pile et de la sérialisation.
- Étiquette du certificat — l’étiquette de l’objet certificat sur le jeton.
- Étiquette de la clé — l’étiquette de l’objet clé privée, lorsqu’elle diffère de l’étiquette du certificat.
- Chaîne — certificats intermédiaires optionnels sous forme DER, lorsque le jeton ne les détient pas.
Vérifie la disponibilité du jeton avant de construire le signataire. La construction lit le certificat depuis le jeton, de sorte qu’un slot ou une étiquette mal configurés échouent rapidement avec une erreur typée plutôt qu’au moment de la signature.
Étape par étape
Section intitulée « Étape par étape »- Confirme que le runtime prend en charge PKCS#11 en vérifiant la disponibilité de l’extension. Ne construis pas le signataire lorsque l’extension est absente.
- Lis le PIN depuis ton gestionnaire de secrets dans une variable qui n’est jamais journalisée.
- Construis le signataire HSM avec le chemin de la bibliothèque, le slot, le PIN et les étiquettes. La construction se connecte et lit le certificat.
- Transmets le signataire à l’orchestrateur de signature du Core via
HsmSignerInterface. L’orchestrateur calcule la plage d’octets, construit les attributs signés CMS, remet les données au jeton et assemble le PDF signé. - Capture l’échec le plus spécifique, journalise un message structurel sans le PIN, et relance l’exception.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\HsmSignerInterface;
/** * Build a hardware-token signer only when the runtime supports it. * * The concrete PKCS#11 signer is resolved through the Core contract so the * caller depends on the interface, not the Enterprise implementation type. * The PIN arrives from a secret resolver; it is never written to source. * * @param callable(): bool $pkcs11Available Reports ext-pkcs11 availability. * @param callable(): HsmSignerInterface $signerFactory Builds the configured token signer. * * @throws \RuntimeException When the PKCS#11 extension is not loaded. * * @return HsmSignerInterface The token signer, ready for the Core orchestrator. */function resolveHsmSigner(callable $pkcs11Available, callable $signerFactory): HsmSignerInterface{ if ($pkcs11Available() !== true) { throw new \RuntimeException( 'PKCS#11 signing requires the ext-pkcs11 extension; install it before signing.', ); }
return $signerFactory();}Le câblage de production — la liste exacte des arguments du constructeur et les types d’exceptions typées — est documenté dans la référence approfondie HSM.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\HsmSignerInterface;use NextPDF\Exception\NextPdfException;use Psr\Log\LoggerInterface;
final readonly class HsmSigningService{ public function __construct( private HsmSignerInterface $signer, private LoggerInterface $logger, ) {}
/** * Sign data on the token through the Core HSM contract. * * The byte range is computed by the engine, never accepted from the * caller. The token performs the signing operation; the private key * does not leave the device. * * @param string $data The bytes the orchestrator hands to the token. * @param string $algorithm The OpenSSL-style signing algorithm identifier. * * @throws NextPdfException When the token operation fails. * * @return string The raw signature bytes returned by the token. */ public function sign(string $data, string $algorithm): string { try { return $this->signer->sign($data, $algorithm); } catch (NextPdfException $e) { // Structural message only — never the PIN or key material. $this->logger->error('HSM signing failed', ['reason' => $e->getMessage()]);
throw $e; } }}Vérification
Section intitulée « Vérification »Confirme le résultat comme le ferait un vérificateur :
- Relis le certificat et la chaîne du signataire sous forme DER depuis le signataire et confirme qu’ils correspondent au certificat approvisionné sur le jeton.
- Ouvre le PDF signé dans un validateur configuré avec tes ancres de confiance et confirme que la signature est rapportée comme cryptographiquement intacte. Une signature produite n’est pas une signature vérifiée ; la décision de confiance revient au vérificateur et à ses ancres de confiance, et non au producteur.
- Pour une signature ECDSA, confirme que la signature intégrée est encodée en DER — le signataire convertit pour toi la sortie brute du jeton, de sorte qu’un validateur qui rejette la forme concaténée brute devrait tout de même accepter la signature intégrée.
- Confirme qu’aucun PIN, étiquette de jeton ou matériel de clé n’apparaît dans tes journaux applicatifs.
Sécurité et conformité
Section intitulée « Sécurité et conformité »- La clé reste sur le jeton. Les données à signer sont remises au jeton ; l’opération de signature s’exécute à l’intérieur de la frontière du jeton. La clé privée n’est jamais chargée dans la mémoire de PHP.
- Le PIN est un secret. C’est un paramètre de constructeur sensible, exclu des journaux et de la sérialisation. Fournis-le depuis un gestionnaire de secrets. Des échecs répétés de réauthentification peuvent verrouiller le PIN au niveau du jeton ; c’est le jeton, et non NextPDF, qui applique cette politique.
- Échec sûr (fail-closed). Une erreur de jeton ou de HSM lève une exception typée. Le signataire ne produit pas de résultat non signé ou partiellement signé et ne substitue jamais un algorithme plus faible.
- Robustesse de l’algorithme. Approvisionne des clés RSA d’au moins 2048 bits et des courbes ECDSA d’un ordre d’au moins 224 bits, les minimums acceptables pour la génération de signature conformément à NIST SP 800-131A Rev.2 §3.
- La signature post-quantique est expérimentale et désactivée par défaut. Un chemin post-quantique existe derrière un indicateur d’activation explicite. Les profils d’archivage à long terme PDF Advanced Electronic Signatures (PAdES) standard ne reconnaissent pas encore les suites post-quantiques, et la plupart des visionneuses les rejettent à la validation. Ne l’active pas pour des signatures PAdES de production.
Cette page concerne la signature cryptographique et l’intégration de module matériel de sécurité. Chaque source normative est paraphrasée ; aucun texte normatif n’est reproduit. ### Frontière de garde des clés
NextPDF Enterprise s’intègre à un jeton PKCS#11 ou à un HSM. Il ne stocke pas, ne génère pas et ne garantit pas la sécurité de la clé de signature. La sécurité des clés dépend du jeton ou du HSM, du déploiement et de l’opérateur — et non de NextPDF Enterprise seul. Tu es responsable de l’approvisionnement du jeton, de la manipulation du PIN, de la configuration du slot et de la protection réseau d’un HSM en réseau.
Gestion des échecs
Section intitulée « Gestion des échecs »- Extension absente. Construire le signataire PKCS#11 lève une exception d’opération typée lorsque
ext-pkcs11n’est pas chargée. Vérifie d’abord la disponibilité. - Certificat ou clé introuvable par étiquette. La construction ou la signature lève une exception typée qui nomme l’objet manquant. Confirme l’étiquette et le slot.
- Déjà connecté. Lorsque plusieurs instances de signataire partagent un module mis en cache pour le même slot, le signataire se déconnecte et se reconnecte pour fournir une vérification de PIN fraîche — requis par les jetons personal-identity-verification avec une politique « PIN à chaque fois ».
- Algorithme non pris en charge. Demander un algorithme que le signataire ne mappe pas lève une erreur d’argument plutôt que de signer avec un substitut.
- HSM en réseau injoignable. Une erreur réseau ou d’appareil lève une exception typée ; le signataire ne produit jamais silencieusement un document non signé.
Frontière de publication
Section intitulée « Frontière de publication »Cette page documente uniquement le comportement observable de l’extérieur et la surface d’API publique prise en charge. Les chemins d’espaces de noms internes, les classes utilitaires, les tables de mécanismes, les noms de fichiers de runbook et les préfixes de tickets sont hors périmètre.
Voir aussi
Section intitulée « Voir aussi »- Signature HSM — référence — la référence approfondie du signataire PKCS#11.
- Security — NextPDF Enterprise — la surface de sécurité Enterprise combinée.
- Signature — NextPDF Enterprise — le producteur à long terme PAdES B-LT et B-LTA.
- Politique cryptographique FIPS 140 — la politique de mode FIPS et la garde d’auto-test.
- Signature cloud KMS — NextPDF Pro — stratégies key-management-service AWS, Azure et GCP.
- Sécurité / Signature (Core) — le signataire CMS du Core et le contrat de stratégie de signature.
- HSM · PKCS#11 · CMS · ECDSA — termes du glossaire.