Sécurité : chiffrement, politique cryptographique et surface de signature
Le module de sécurité Core applique le chiffrement AES-256 des documents, soumet chaque choix d’algorithme à un contrat de politique cryptographique et expose les points d’intégration qu’un déploiement utilise pour se connecter à un service de gestion de clés. La protection effective d’un document dépend de la gestion des clés, de la robustesse du mot de passe, du lecteur qui l’ouvre et de l’environnement de déploiement — cette page explicite chacune de ces limites.
Installation
Section intitulée « Installation »composer require nextpdf/core:^3Aperçu conceptuel
Section intitulée « Aperçu conceptuel »Le module de sécurité regroupe trois surfaces. La première concerne le chiffrement : le point d’entrée setEncryption() du document configure le gestionnaire de sécurité Standard AES-256. La deuxième est le gate de politique cryptographique : CryptoPolicyInterface décide quels algorithmes de hachage, de signature et de chiffrement, ainsi que quelles robustesses de clé, un déploiement autorise. La troisième est la surface de signature, référencée ici sans être documentée — voir Signature.
Le chiffrement utilise AES-256 tel que défini dans ISO 32000-2:2020 §7.6. Le chemin par défaut est celui du gestionnaire de sécurité Standard V=5 / R=6 avec le filtre de chiffrement AESV3. La clé de fichier fait 32 octets (256 bits), conformément à FIPS 197. Un chemin optionnel ajoute le chiffrement authentifié AES-256-GCM V=6 / R=7 défini par ISO/TS 32003:2023. La page détaillée documente les deux : Chiffrement.
Le gate de politique cryptographique est un prédicat de refus ou d’autorisation. Core consulte CryptoPolicyInterface avant toute étape de signature, de chiffrement ou de hachage. En l’absence de politique définie, Core autorise chaque algorithme : ce comportement ouvert par défaut convient au développement, pas à une posture de production. Un déploiement réglementé doit définir une politique explicite. Contrats / Politique de sécurité documente la surface du contrat.
Les drapeaux de permission sont le point le plus souvent surestimé ; cette page reste donc explicite. Le masque de bits de permission circule dans l’entrée chiffrée /Perms et la valeur /P. Un lecteur conforme est censé respecter les restrictions. Les drapeaux ne sont pas imposés par la cryptographie. Un processeur qui ignore les bits peut encore lire, copier ou modifier le contenu une fois en possession de la clé de déchiffrement. Énonce cette limite à toute partie qui s’appuie sur les drapeaux de permission.
La gestion des clés et l’intégration PKCS#11 sont des points de contrat. Core fournit un chemin de clé locale. L’objet-valeur KeyMaterial encapsule une clé de 256 bits dont la longueur est vérifiée, et empêche la divulgation via ses représentations en chaîne et de débogage. Le chemin de garde de clé HSM et PKCS#11 est une capacité Enterprise, contrôlée par les mêmes contrats ; cette page nomme le point d’intégration sans documenter l’implémentation Enterprise.
Surface d’API
Section intitulée « Surface d’API »| Type | Nature | Membres clés | Stabilité | Depuis |
|---|---|---|---|---|
Document::setEncryption() | méthode (concern HasSecurity) | userPassword, ownerPassword, permissions | stable | 1.0.0 |
Document::useAesGcm() | méthode (concern HasSecurity) | ?bool $enabled — option ISO/TS 32003 V=6/R=7 | stable | 2.18.0 |
Aes256Encryptor | classe | encrypt(), decrypt(), buildEncryptionDictionary(), verifyUserPassword(), verifyOwnerPassword(), validatePerms() | stable | 1.0.0 |
Aes256GcmEncryptor | classe | encrypt(), decrypt(), encryptStream(), assertWithinSafetyBound(), invocationCount() | stable | 2.18.0 |
KeyMaterial | classe final readonly | generate(), exposeKey(), fingerprint() | stable | 2.18.0 |
CryptoPolicyInterface | interface | isHashAlgorithmAllowed(), isSignatureAlgorithmAllowed(), isEncryptionAlgorithmAllowed(), isKeyStrengthAllowed(), getPreferredHashAlgorithm(), getName() | stable | 1.9.0 |
Config::withCryptoPolicy() | méthode | CryptoPolicyInterface $policy | stable | 1.9.0 |
CryptoCapabilities | classe final | hasAesGcm(), detectFipsMode(), assertFipsAvailableForProfile() | stable | 2.0.0 |
Exemple de code — Démarrage rapide
Section intitulée « Exemple de code — Démarrage rapide »<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Encrypted Document — Restricted Permissions');
// Call setEncryption() BEFORE addPage().// Permission bit 3 (value 4) = printing allowed; all other operations denied.$doc->setEncryption( userPassword: 'demo', ownerPassword: 'admin', permissions: 4,);
$doc->addPage();$doc->setFont('helvetica', 'B', 20);$doc->cell(0, 14, 'Encrypted PDF Document', newLine: true);
$doc->save(__DIR__ . '/output/22-protection.pdf');Le mot de passe utilisateur ouvre le document. Le mot de passe propriétaire donne un accès complet. Les drapeaux de permission ne contraignent qu’un lecteur conforme.
Exemple de code — Production
Section intitulée « Exemple de code — Production »<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\CryptoPolicyInterface;use NextPDF\Core\Document;use Psr\Log\LoggerInterface;
final readonly class PolicyGatedEncryption{ public function __construct( private CryptoPolicyInterface $cryptoPolicy, private LoggerInterface $logger, ) {}
/** * Encrypt only when the active policy permits AES-256-CBC. * * @param non-empty-string $userPassword Opens the document. * @param non-empty-string $ownerPassword Grants full access. */ public function protect( Document $doc, string $userPassword, string $ownerPassword, int $permissions, ): void { if (!$this->cryptoPolicy->isEncryptionAlgorithmAllowed('aes-256-cbc')) { $this->logger->error('Encryption refused by crypto policy', [ 'policy' => $this->cryptoPolicy->getName(), ]);
throw new \RuntimeException('AES-256-CBC denied by the active crypto policy.'); }
$doc->setEncryption($userPassword, $ownerPassword, $permissions);
$this->logger->info('Document encrypted', [ 'policy' => $this->cryptoPolicy->getName(), 'algorithm' => 'aes-256-cbc', ]); }}Le gate consulte la politique avant le chiffrement, journalise le nom de la politique pour la piste d’audit et refuse l’opération avec une exception spécifique lorsque la politique interdit le chiffrement.
Cas limites & pièges
Section intitulée « Cas limites & pièges »- Appelle
setEncryption()avantaddPage(). Un appel ultérieur ne chiffre pas rétroactivement le contenu déjà émis par le writer. - Le mode PDF/A et le chiffrement s’excluent mutuellement. ISO 19005 interdit la clé de trailer
Encryptdans chaque variante de PDF/A ;setEncryption()etuseAesGcm()lèvent donc une exception lorsqu’un gestionnaire PDF/A est actif. - Un mot de passe propriétaire vide se rabat sur le mot de passe utilisateur dans
setEncryption(). Un document avec un seul mot de passe partagé donne au détenteur du mot de passe utilisateur un accès de niveau propriétaire. CryptoPolicyInterfaceautorise chaque algorithme lorsqu’aucune politique n’est injectée. Considère ce comportement ouvert par défaut comme une commodité de développement, et définis une politique explicite dans tout déploiement réglementé.- Les drapeaux de permission sont consultatifs pour le lecteur. Ne les présente pas comme un contrôle d’accès qu’un processeur hostile ne pourrait pas contourner.
Performance
Section intitulée « Performance »setEncryption() exécute une routine itérée de dérivation de clé (Algorithme 2.B, révision 6) lors de la construction du document. Son coût est borné et constant par document, et non proportionnel au nombre de pages. Le chiffrement par objet correspond à une opération AES par flux ou par chaîne. Le chemin AES-256-GCM optionnel ajoute une surcharge de 28 octets par objet (IV de 12 octets plus tag de 16 octets) et traite les contenus volumineux en flux, par blocs de 16 MiB. La passe de diffusion reste ainsi sous le pic documenté de 64 Mo. Le performance_budget de 1500 ms en temps réel et 64 Mo de pic mémoire est dominé par le rendu du document, pas par l’étape de chiffrement.
Notes de sécurité
Section intitulée « Notes de sécurité »Le modèle de menace est explicite. La rétrogradation d’algorithme est atténuée par le gate de politique cryptographique, qui refuse les chiffrements faibles, les hachages faibles et les clés courtes avant toute opération. Le moteur ne remplace pas silencieusement une primitive par une autre plus faible lorsqu’une primitive demandée est absente : il lève une exception pour que l’opérateur puisse agir. La divulgation de clé par journalisation est atténuée par KeyMaterial, dont les formes en chaîne et de débogage masquent les octets et n’exposent qu’une empreinte non réversible. La falsification du texte chiffré n’est détectée que sur le chemin AES-256-GCM optionnel, où le tag d’authentification est vérifié ; en cas de non-correspondance, une exception est levée au lieu de renvoyer le texte en clair. Le chemin AES-256-CBC par défaut assure uniquement la confidentialité et ne détecte pas à lui seul les modifications. La réutilisation de l’IV sur le chemin GCM est atténuée par un compteur monotone et un ensemble de collisions en défense en profondeur, conformément à l’exigence d’IV unique de NIST SP 800-38D §8.
La limite est tout aussi explicite. Le chiffrement AES-256 est appliqué tel que défini dans ISO 32000-2:2020 §7.6. La protection effective dépend de la robustesse du mot de passe, de la gestion des clés, de l’environnement de déploiement et du lecteur qui l’ouvre. Les drapeaux de permission sont respectés par les lecteurs conformes et ne sont pas imposés par la cryptographie. La sonde de mode FIPS indique si la version OpenSSL de l’hôte a chargé un fournisseur FIPS. La bibliothèque opère dans un mode compatible FIPS lorsque l’hôte fournit un module validé, et elle ne certifie elle-même aucun module. NIST SP 800-57 Partie 1 §4 présente la durée de vie de la clé et la cryptopériode comme une responsabilité du déploiement. Core expose les contrôles, mais la politique de rotation relève du déploiement.
Résidence des données & atténuations relatives aux DCP
Section intitulée « Résidence des données & atténuations relatives aux DCP »La surface de chiffrement ne transmet pas les octets du document hors de l’hôte. La dérivation de clé, le chiffrement et le déchiffrement s’exécutent dans le processus. Le chemin GCM optionnel indexe en mémoire un ensemble de collisions d’IV sur une empreinte de clé non réversible, et non sur les octets de la clé. Aucune valeur de mot de passe ou de clé n’est écrite sur disque par le module de sécurité. Un déploiement qui route les clés via un service externe de gestion de clés est responsable de la résidence de ce service.
Télémétrie sûre & nettoyage des journaux
Section intitulée « Télémétrie sûre & nettoyage des journaux »KeyMaterial::__toString() et __debugInfo() renvoient un substitut masqué, si bien que la journalisation accidentelle d’un objet de clé produit une empreinte, pas les octets de la clé. Les mots de passe passés à setEncryption() portent l’attribut #[\SensitiveParameter], qui les masque dans une trace de pile. Les identifiants adaptés à l’audit pour une opération cryptographique sont le nom de la politique fourni par CryptoPolicyInterface::getName() et l’empreinte de clé à 8 caractères : journalise ces valeurs, jamais la clé ni le mot de passe.
Modèle de menace
Section intitulée « Modèle de menace »| Menace | Atténuation dans Core | Limite résiduelle |
|---|---|---|
| Rétrogradation d’algorithme / substitution par un chiffrement faible | Gate de politique cryptographique ; aucune dégradation silencieuse (lève UnsupportedAlgorithmException) | Efficace uniquement lorsqu’une politique est injectée |
| Divulgation de clé via les journaux | KeyMaterial masque les octets ; #[\SensitiveParameter] sur les mots de passe | Un appelant qui transmet exposeKey() à un logger contourne cette protection |
| Falsification du texte chiffré | Vérification du tag GCM sur le chemin optionnel | Le chemin CBC par défaut assure uniquement la confidentialité |
| Réutilisation de l’IV (GCM) | Compteur monotone et ensemble de collisions ; le dépassement de capacité refuse l’opération | — |
| Contournement des drapeaux de permission | Aucune — les drapeaux sont consultatifs | Un lecteur non conforme ignore les drapeaux |
| Attaque par force brute sur un mot de passe faible | SASLprep et la dérivation de clé itérée augmentent le coût | Un mot de passe faible reste le risque dominant |
Comportement en mode FIPS
Section intitulée « Comportement en mode FIPS »Core n’est pas un module cryptographique validé FIPS et n’est pas certifié FIPS. CryptoCapabilities::detectFipsMode() est une sonde d’exécution limitée : elle lit un forçage défini par l’opérateur, puis la liste des fournisseurs OpenSSL, puis l’appel hérité au mode FIPS, et indique actif, absent ou indéterminé. assertFipsAvailableForProfile() échoue en mode fermé lorsqu’un profil FIPS est sélectionné sur un hôte qui ne prouve pas la présence d’un fournisseur FIPS. La bibliothèque opère dans un mode compatible FIPS lorsqu’elle est configurée sur une version OpenSSL de l’hôte qui a chargé un fournisseur validé FIPS. Une posture FIPS validée et certifiée relève d’Enterprise ; voir la documentation Enterprise.
Conformité
Section intitulée « Conformité »| Affirmation | Norme | Clause | Preuve |
|---|---|---|---|
| Le chemin GCM garde un IV unique à chaque invocation, conformément à l’exigence d’unicité de la norme. | NIST SP 800-38D | §8.2.1 | |
| La durée de vie de la clé et la cryptopériode relèvent du déploiement, et Core expose les contrôles correspondants. | NIST SP 800-57 Partie 1 Rév. 5 | §4 | |
| La clé de fichier AES est de 256 bits, conformément à la longueur de clé de la norme. | FIPS 197 | §4.2.1 | |
| La génération de clé résidente sur jeton constitue le point d’intégration pour un magasin de clés externe. | OASIS PKCS#11 v3.1 | C_GenerateKey |
ISO 32000-2:2020 §7.6 est la base normative du gestionnaire de sécurité Standard. Son texte est soumis à des restrictions de licence et est paraphrasé ici, jamais cité ; la clause est référencée par numéro. Chaque point ci-dessus est paraphrasé à partir de la norme citée.
Contexte commercial
Section intitulée « Contexte commercial »Core définit et fige le contrat de politique cryptographique, fournit le chemin de chiffrement AES-256 et propose une surface de clé locale. L’édition Enterprise fournit un chemin de garde de clé HSM/PKCS#11 et un profil de politique cryptographique en mode FIPS derrière le même CryptoPolicyInterface. La surface du contrat est identique d’une édition à l’autre ; la différence tient à l’implémentation de la politique et au backend de garde de clé injecté par le déploiement.
Voir aussi
Section intitulée « Voir aussi »- Sécurité / Chiffrement — la référence détaillée d’AES-256 et AES-256-GCM.
- Contrats / Politique de sécurité — les contrats de politique cryptographique et de politique de ressources.
- Sécurité / Signature — les signatures PAdES, CMS et les horodatages.
- Audit — journalisation d’audit du nom de la politique et des opérations.
- Conformité — interaction du PDF/A avec le chiffrement.