Pro édition
Signature Cloud KMS — référence approfondie
Cette page constitue la référence au niveau du contrat pour la surface de signature cloud-KMS de NextPDF Pro. La surface se compose d’une unique interface de fournisseur de service (Service Provider Interface), NextPDF\Pro\Security\Signing\Kms\KmsSignerInterface, et de trois signataires de fournisseur : AwsKmsSigner, AzureKeyVaultSigner et GcpKmsSigner. Deux adaptateurs, AwsKmsSigningStrategy et AzureKeyVaultSigningStrategy, relient un signataire au contrat SigningStrategy de Pro. Chaque signataire n’envoie qu’un condensé de message à son fournisseur via HTTP PSR-18. La clé privée et le document ne franchissent jamais la frontière. Cette page énonce l’API publique, le contrat de comportement observable et les modes d’échec typés. L’orchestration de session (RemoteSigningSession, SequentialSigner) et l’horodatage (PadesBtTimestamper) figurent sur leurs propres pages.
Disponibilité et licence
Section intitulée « Disponibilité et licence »Cette fonctionnalité est livrée dans NextPDF Pro (nextpdf/pro) et s’active avec une enveloppe de licence de niveau Pro. Un déploiement sans ce droit ne charge pas les classes de la fonctionnalité. Comparer les éditions et obtenir une licence.
Surface d’API publique
Section intitulée « Surface d’API publique »| Symbole | Paramètres | Comportement par défaut | Retourne | Lève ou échoue avec | Notes |
|---|---|---|---|---|---|
KmsSignerInterface | — | Étend le contrat Core HsmSignerInterface | — | — | SPI pour les pilotes KMS et HSM ; identifiants intégrés réservés : aws-kms, azure-keyvault, gcp-kms, pkcs11, openssl-cli |
KmsSignerInterface::providerId() | aucun | Clé de recherche stable dans le registre | non-empty-string | — | Les pilotes tiers doivent placer leur identifiant dans un espace de noms |
KmsSignerInterface::signWithVersion() | $data, $algorithm = 'sha256WithRSAEncryption', $keyVersion = null | une version de clé null retombe sur la valeur par défaut du fournisseur | octets de signature string : RSA tels que renvoyés par le fournisseur (placés directement dans SignerInfo.signature), ECDSA au format DER ECDSA-Sig-Value selon les règles CMS | KeyManagementException, UnsupportedAlgorithmException, SignatureFailedException | la sémantique de null diffère selon le fournisseur ; voir le contrat de comportement |
KmsSignerInterface::supportsAlgorithm() | string $algorithm | Sonde de capacité ; n’effectue aucune E/S | bool | — | Appelée avant la sélection du fournisseur |
KmsSignerInterface::supportedAlgorithms() | aucun | Liste les noms de style OpenSSL acceptés par le fournisseur | list<non-empty-string> | — | — |
AwsKmsSigner | constructeur : AwsKmsConfig, cert DER, chaîne DER, client PSR-18, fabriques PSR-17, journaliseur PSR-3 | l’algorithme par défaut est KmsSigningAlgorithm::RsaPkcs1Sha256 | — | voir les méthodes | final ; PROVIDER_ID = 'aws-kms' |
AwsKmsSigner::create() | identifiant de clé, cert DER, dépendances PSR, chaîne optionnelle, config, journaliseur | construit AwsKmsConfig::fromEnvironment($keyId) lorsque $config vaut null | self | — | Lit les variables d’environnement AWS_* standard |
AwsKmsSigner::withAlgorithm() | KmsSigningAlgorithm $algorithm | Retourne un clone modifié | self | — | Doit correspondre au type de clé provisionné dans AWS KMS |
AwsKmsSigner::sign() | $data, $algorithm = 'sha256WithRSAEncryption' | Délègue à signWithVersion($data, $algorithm, null) | string | comme signWithVersion() | Chemin hérité du contrat Core à deux arguments |
AzureKeyVaultSigner | constructeur : AzureKeyVaultConfig, cert DER, chaîne DER, client PSR-18, fabriques PSR-17, journaliseur PSR-3 | l’algorithme par défaut est AzureSigningAlgorithm::Rs256 ; un jeton d’accès de configuration amorce le jeton bearer | — | voir les méthodes | final ; PROVIDER_ID = 'azure-keyvault' |
AzureKeyVaultSigner::create() | nom du coffre, nom de la clé, cert DER, dépendances PSR, chaîne optionnelle, config, journaliseur | construit AzureKeyVaultConfig::fromEnvironment() lorsque $config vaut null | self | — | Prend en charge un jeton pré-obtenu ou des identifiants de principal de service |
AzureKeyVaultSigner::withAlgorithm() | AzureSigningAlgorithm $algorithm | Retourne un clone modifié | self | — | Les clés RSA utilisent des valeurs RS/PS ; les clés EC utilisent des valeurs ES |
GcpKmsSigner | constructeur : GcpKmsConfig, cert DER, chaîne DER, client PSR-18, fabriques PSR-17, journaliseur PSR-3 | l’algorithme par défaut est GcpKmsSigningAlgorithm::RsaSignPkcs1_2048Sha256 | — | voir les méthodes | final ; PROVIDER_ID = 'gcp-kms', API_VERSION = 'v1' |
GcpKmsSigner::create() | identifiant de projet, emplacement, trousseau de clés, clé cryptographique, cert DER, dépendances PSR, chaîne optionnelle, config, journaliseur | construit GcpKmsConfig::fromEnvironment() lorsque $config vaut null | self | — | L’acquisition du jeton bearer est déléguée à l’appelant |
GcpKmsSigner::withAlgorithm() | GcpKmsSigningAlgorithm $algorithm | Aperçu au moment de la configuration uniquement ; le nom filaire par appel l’emporte au moment de la signature | self | — | La taille de clé est fixée par la CryptoKeyVersion provisionnée |
AwsKmsSigningStrategy | constructeur : AwsKmsSigner $signer | Synchrone ; isAsync() retourne false | — | Propage les exceptions du signataire encapsulé | Adaptateur pour RemoteSigningSession::complete() |
AzureKeyVaultSigningStrategy | constructeur : AzureKeyVaultSigner $signer | Synchrone ; isAsync() retourne false | — | Propage les exceptions du signataire encapsulé | Adaptateur pour RemoteSigningSession::complete() |
KmsSigningAlgorithm | enum, 9 cas (RSA PKCS#1, RSA-PSS, ECDSA ; SHA-256/384/512) | — | valeurs filaires SigningAlgorithm d’AWS KMS | InvalidArgumentException depuis fromOpenSslName() | resolveForWireName() préserve le condensé PSS configuré |
AzureSigningAlgorithm | enum, 9 cas (RS256…ES512) | — | valeurs de style JWA d’Azure Key Vault | InvalidArgumentException depuis fromOpenSslName() | isEcdsa() marque les valeurs dont la sortie nécessite une conversion DER |
GcpKmsSigningAlgorithm | enum, 10 cas (EC P-256/P-384, RSA PKCS#1, RSA-PSS) | — | valeurs d’algorithme CryptoKeyVersion de GCP | UnsupportedAlgorithmException depuis fromOpenSslName() | La résolution du nom filaire choisit la plus petite taille de clé correspondante |
Signatures des points d’entrée
Section intitulée « Signatures des points d’entrée »public function providerId(): string;
public function signWithVersion( string $data, string $algorithm = 'sha256WithRSAEncryption', ?string $keyVersion = null,): string;
public function supportsAlgorithm(string $algorithm): bool;
public function supportedAlgorithms(): array;public static function create( string $keyId, string $certDer, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, array $chainDer = [], ?AwsKmsConfig $config = null, ?LoggerInterface $logger = null,): self
public function withAlgorithm(KmsSigningAlgorithm $algorithm): self
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): stringpublic static function create( string $vaultName, string $keyName, string $certDer, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, array $chainDer = [], ?AzureKeyVaultConfig $config = null, ?LoggerInterface $logger = null,): self
public function withAlgorithm(AzureSigningAlgorithm $algorithm): selfpublic static function create( string $projectId, string $location, string $keyRing, string $cryptoKey, string $certDer, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, array $chainDer = [], ?GcpKmsConfig $config = null, ?LoggerInterface $logger = null,): self
public function withAlgorithm(GcpKmsSigningAlgorithm $algorithm): selfpublic function __construct( private AwsKmsSigner $signer,) {}
public function sign(string $signedAttributesDer): stringpublic function __construct( private AzureKeyVaultSigner $signer,) {}
public function sign(string $signedAttributesDer): stringContrat de comportement
Section intitulée « Contrat de comportement »Résolution du contrat
Section intitulée « Résolution du contrat »KmsSignerInterface étend le contrat Core HsmSignerInterface. Il ajoute providerId(), la méthode signWithVersion() tenant compte de la version de clé, ainsi que les sondes de capacité supportsAlgorithm() et supportedAlgorithms(). La méthode héritée sign() à deux arguments délègue à signWithVersion() avec une version de clé null sur les trois signataires. getCertificateDer(), getCertificateChainDer() et getPublicKeyAlgorithm() sont implémentées à partir du matériel fourni au constructeur. Les sondes de capacité n’effectuent aucune E/S. Chaque signataire expose également les accesseurs getSigningAlgorithm() et getConfig() à des fins d’inspection.
Transmission du seul condensé
Section intitulée « Transmission du seul condensé »Chaque signataire hache $data localement avec le condensé de l’algorithme résolu et ne transmet que ce condensé. AWS reçoit un condensé base64 avec MessageType: DIGEST. Azure reçoit un condensé base64url dans le corps de la requête de signature. GCP reçoit un condensé base64 dans le champ de condensé propre à l’algorithme. Les octets du document n’apparaissent jamais dans une requête vers le fournisseur. Tout le transport utilise un client HTTP PSR-18 standard sur le point de terminaison HTTPS du fournisseur ; aucun SDK d’éditeur cloud n’est impliqué.
Résolution de la version de clé
Section intitulée « Résolution de la version de clé »signWithVersion() valide l’argument de version de clé en mode fail-closed avant la construction de toute requête. Une valeur qui ne respecte pas la grammaire du fournisseur lève KeyManagementException et empêche l’injection dans un segment d’URL ou dans le KeyId.
| Fournisseur | Version de clé null | Chaîne vide | Grammaire de remplacement |
|---|---|---|---|
AwsKmsSigner | Utilise AwsKmsConfig::$keyId ; un alias ou un ARN se résout vers la clé courante côté fournisseur | Rejetée | UUID (avec ou sans tirets), alias/<name>, ou un ARN de clé/alias KMS |
AzureKeyVaultSigner | Utilise la version de clé configurée ; une valeur de configuration vide sélectionne côté serveur la dernière version activée | Rejetée | Identifiant hexadécimal de 32 caractères |
GcpKmsSigner | Utilise la version épinglée dans GcpKmsConfig ; si aucune n’est épinglée, lève KeyManagementException | Rejetée | Identifiant CryptoKeyVersion décimal, chiffres uniquement |
GCP ne dispose d’aucune primitive de « version active » côté serveur. Le point de terminaison de signature asymétrique n’opère que sur une ressource cryptoKeyVersions/{n} spécifique, si bien qu’une version doit toujours pouvoir être résolue.
Résolution de l’algorithme
Section intitulée « Résolution de l’algorithme »La couche de stratégie transmet un nom filaire de style OpenSSL. AWS et Azure acceptent sept noms filaires (PKCS#1 et ECDSA en SHA-256/384/512, plus RSASSA-PSS). GCP en accepte cinq (sha256WithRSAEncryption, sha512WithRSAEncryption, RSASSA-PSS, ecdsa-with-SHA256, ecdsa-with-SHA384). Le nom filaire RSASSA-PSS n’encode pas de condensé, il est donc ambigu quant au condensé. AwsKmsSigner le résout via KmsSigningAlgorithm::resolveForWireName(), qui préserve le condensé de la variante PSS configurée. AzureKeyVaultSigner fait confiance à la variante PSS configurée pour le nom ambigu. Il lève UnsupportedAlgorithmException si un condensé PSS résolu venait à diverger de celui configuré. GcpKmsSigner re-résout l’enum à partir du nom filaire à chaque appel ; withAlgorithm() sur GCP est un aperçu au moment de la configuration et ne modifie pas le comportement au moment de la signature. Un nom filaire non pris en charge lève UnsupportedAlgorithmException avant tout appel réseau. Sur AwsKmsSigner et GcpKmsSigner, un appel de signature met à jour la valeur ultérieurement rapportée par getSigningAlgorithm() avec l’algorithme résolu par appel. Sur AzureKeyVaultSigner, la résolution est locale à l’appel et la valeur configurée reste faisant autorité.
Normalisation de la signature
Section intitulée « Normalisation de la signature »AWS et GCP renvoient les signatures sous la forme que CMS consomme : les octets de signature RSA vont dans SignerInfo.signature sans modification, et l’ECDSA arrive encodé en DER. Azure renvoie l’ECDSA sous forme brute IEEE P1363 (r||s), que le signataire convertit en un ECDSA-Sig-Value DER avant de le renvoyer.
Intégration CMS et adjacence
Section intitulée « Intégration CMS et adjacence »Un adaptateur SigningStrategy signe les attributs signés encodés en DER fournis par la session. En présence d’attributs signés, l’entrée de signature CMS est le condensé de l’encodage DER complet de la valeur SignedAttrs — RFC 5652 §5.4. Les méthodes getSignatureAlgorithmOid() et getDigestAlgorithm() de l’adaptateur alimentent les champs signatureAlgorithm et digestAlgorithm du SignerInfo — RFC 5652 §5.3. Les octets renvoyés deviennent l’OCTET STRING de signature du SignerInfo — RFC 5652 §5.5. L’assemblage CMS, la gestion du ByteRange et le cycle de vie de la session relèvent de RemoteSigningSession ; les flux multipartites relèvent de SequentialSigner. Un horodatage de signature PAdES B-T, dont le messageImprint hache la valeur de signature du SignerInfo — RFC 3161 Appendix A — est appliqué par PadesBtTimestamper, et non par ces signataires. Les trois sont documentés dans la référence approfondie de sécurité Pro.
Cas limites et modes d’échec
Section intitulée « Cas limites et modes d’échec »- Une version de clé sous forme de chaîne vide est rejetée sur les trois fournisseurs. Passe
nullpour hériter de la valeur par défaut configurée. - Une version de clé malformée est rejetée avant la construction de toute requête, la valeur fautive étant nommée dans l’exception.
AwsKmsSigneravec unAwsKmsConfig::$keyIdvide et une version de clénulllèveKeyManagementException.- Les réponses du fournisseur qui indiquent un échec de gestion de clé se mappent à
KeyManagementException: AWSNotFoundException,DisabledException,KeyUnavailableException,InvalidKeyUsageException, ou HTTP 404 ; Azure HTTP 404,KeyNotFound,KeyDisabled, ouKeyNotActive; GCP HTTP 404 ou 409,NOT_FOUND,FAILED_PRECONDITION, ou un HTTP 400 dont le message nomme une version. - Les autres réponses du fournisseur non-200 lèvent
SignatureFailedExceptionsur AWS et GCP, etAzureKeyVaultExceptionsur Azure. - Un échec de transport PSR-18 pendant la signature se mappe à
SignatureFailedException, l’exception du client étant préservée comme throwable précédent. AzureKeyVaultSignersans jeton d’accès ni identifiants de principal de service lèveAzureKeyVaultExceptionavant tout appel au coffre. Une acquisition de jeton Azure AD ayant échoué lève égalementAzureKeyVaultException.AzureKeyVaultSignervalide le nom du coffre, le nom de la clé, la version de clé et l’identifiant de locataire au regard des grammaires publiées par Azure, au point de passage obligé de la requête. Une valeur porteuse de caractères à structure d’URL échoue en mode fail-closed avecAzureKeyVaultException.GcpKmsSignersans jeton bearer OAuth2 lèveSignatureFailedException; l’acquisition du jeton est de la responsabilité de l’appelant.- Une réponse du fournisseur qui n’est pas du JSON valide, ou qui ne contient pas le champ de signature, lève
SignatureFailedException(Azure : un champvaluemanquant lèveAzureKeyVaultException). - Un champ de signature du fournisseur dont le décodage base64 échoue lève
SignatureFailedExceptionsur AWS et GCP, etAzureKeyVaultExceptionsur Azure. - Aucun adaptateur
SigningStrategypourGcpKmsSignern’est livré dans la 3.1.0. Le signataire GCP est consommé directement via le contratKmsSignerInterface.
Comportement en mode FIPS
Section intitulée « Comportement en mode FIPS »AwsKmsConfig::withFipsEndpoint() achemine les requêtes vers le point de terminaison kms-fips de la région. Le statut de validation FIPS de ce point de terminaison est une propriété d’AWS, pas de NextPDF. AzureKeyVaultConfig et GcpKmsConfig n’exposent aucun assistant de point de terminaison FIPS dédié dans la 3.1.0. Le calcul du condensé s’exécute en cours de processus avec la fonction PHP hash() et n’est pas lui-même un module validé. NextPDF Pro peut fonctionner face à une frontière KMS ou HSM validée FIPS, mais NextPDF n’est pas un module cryptographique validé FIPS et ne formule aucune revendication de certification FIPS.
Conformité
Section intitulée « Conformité »| Revendication | Norme | Clause |
|---|---|---|
| La stratégie signe les attributs signés encodés en DER ; le condensé d’entrée de signature CMS couvre l’encodage DER complet de SignedAttrs. | RFC 5652 | §5.4 |
| Les SignedAttributes sont encodés en DER et portent au minimum content-type et message-digest ; signatureAlgorithm identifie l’algorithme du signataire. | RFC 5652 | §5.3 |
| Les octets de signature renvoyés sont encodés en OCTET STRING et portés dans le champ de signature du SignerInfo. | RFC 5652 | §5.5 |
| Le messageImprint d’un horodatage de signature hache la valeur de signature du SignerInfo (surface B-T adjacente, pas ces signataires). | RFC 3161 | Appendix A |
Toutes les clauses sont paraphrasées ; NextPDF ne reproduit pas le texte normatif. Ce sont des énoncés de capacité, pas des certifications. NextPDF ne détient aucune certification et n’en accorde aucune. Le fait qu’une signature produite soit vérifiée ou non est la décision du vérificateur au regard de ses propres ancres de confiance et de sa politique ; les signataires renvoient des octets de signature et n’affirment aucun résultat de confiance. La garde des clés, la protection des clés et la validation d’algorithme côté fournisseur sont des propriétés du KMS configuré, pas de NextPDF.
Notes de développement
Section intitulée « Notes de développement »- Disponibilité au sein du package Pro :
AwsKmsSignerdepuis la 1.9.0,AzureKeyVaultSignerdepuis la 2.0.0,GcpKmsSigneretKmsSignerInterfacedepuis la 2.1.0. Tous sont à jour dansnextpdf/pro3.1.0. - Les signataires ne dépendent que de PSR-18, PSR-17 et PSR-3. Aucun SDK AWS, Azure ou Google n’est requis ni fourni.
- Sonde
supportsAlgorithm()avant de signer afin qu’un fournisseur incompatible soit rejeté au moment de la sélection, et non en cours de session. - Les champs d’identifiants sont injectés par le constructeur et marqués comme paramètres sensibles. Les messages de journal ne portent que des champs structurels ; aucun identifiant, jeton ou contenu de document n’est écrit dans les journaux.
- Épingle explicitement les versions de clé dans les déploiements réglementés. Les valeurs par défaut de résolution d’alias (AWS) et de dernière version activée (Azure) sont pratiques mais non déterministes au fil des rotations.
- Les pilotes tiers implémentent
KmsSignerInterfaceet doivent placer leurproviderId()dans un espace de noms afin d’éviter les collisions avec les identifiants intégrés réservés.
Voir aussi
Section intitulée « Voir aussi »- Signature Cloud KMS (fonctionnalité) — la page pratique : installation, configuration et frontière de garde des clés.
- Sécurité — référence approfondie —
RemoteSigningSession,SequentialSigner, la surface PAdES B-B/B-T et le contratSigningStrategy. - Signature — référence approfondie (Enterprise) — la frontière du producteur long terme B-LT/B-LTA.
- Sécurité / Signature (Core) — le signataire CMS Core et les contrats que cette surface étend.
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 d’assistance, les tables de mécanismes, les noms de fichiers de runbook et les préfixes de ticket sont hors périmètre.