Aller au contenu
getnextpdf.com

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.

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.

SymboleParamètresComportement par défautRetourneLève ou échoue avecNotes
KmsSignerInterfaceÉtend le contrat Core HsmSignerInterfaceSPI pour les pilotes KMS et HSM ; identifiants intégrés réservés : aws-kms, azure-keyvault, gcp-kms, pkcs11, openssl-cli
KmsSignerInterface::providerId()aucunClé de recherche stable dans le registrenon-empty-stringLes pilotes tiers doivent placer leur identifiant dans un espace de noms
KmsSignerInterface::signWithVersion()$data, $algorithm = 'sha256WithRSAEncryption', $keyVersion = nullune version de clé null retombe sur la valeur par défaut du fournisseuroctets 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 CMSKeyManagementException, UnsupportedAlgorithmException, SignatureFailedExceptionla sémantique de null diffère selon le fournisseur ; voir le contrat de comportement
KmsSignerInterface::supportsAlgorithm()string $algorithmSonde de capacité ; n’effectue aucune E/SboolAppelée avant la sélection du fournisseur
KmsSignerInterface::supportedAlgorithms()aucunListe les noms de style OpenSSL acceptés par le fournisseurlist<non-empty-string>
AwsKmsSignerconstructeur : AwsKmsConfig, cert DER, chaîne DER, client PSR-18, fabriques PSR-17, journaliseur PSR-3l’algorithme par défaut est KmsSigningAlgorithm::RsaPkcs1Sha256voir les méthodesfinal ; PROVIDER_ID = 'aws-kms'
AwsKmsSigner::create()identifiant de clé, cert DER, dépendances PSR, chaîne optionnelle, config, journaliseurconstruit AwsKmsConfig::fromEnvironment($keyId) lorsque $config vaut nullselfLit les variables d’environnement AWS_* standard
AwsKmsSigner::withAlgorithm()KmsSigningAlgorithm $algorithmRetourne un clone modifiéselfDoit correspondre au type de clé provisionné dans AWS KMS
AwsKmsSigner::sign()$data, $algorithm = 'sha256WithRSAEncryption'Délègue à signWithVersion($data, $algorithm, null)stringcomme signWithVersion()Chemin hérité du contrat Core à deux arguments
AzureKeyVaultSignerconstructeur : AzureKeyVaultConfig, cert DER, chaîne DER, client PSR-18, fabriques PSR-17, journaliseur PSR-3l’algorithme par défaut est AzureSigningAlgorithm::Rs256 ; un jeton d’accès de configuration amorce le jeton bearervoir les méthodesfinal ; PROVIDER_ID = 'azure-keyvault'
AzureKeyVaultSigner::create()nom du coffre, nom de la clé, cert DER, dépendances PSR, chaîne optionnelle, config, journaliseurconstruit AzureKeyVaultConfig::fromEnvironment() lorsque $config vaut nullselfPrend en charge un jeton pré-obtenu ou des identifiants de principal de service
AzureKeyVaultSigner::withAlgorithm()AzureSigningAlgorithm $algorithmRetourne un clone modifiéselfLes clés RSA utilisent des valeurs RS/PS ; les clés EC utilisent des valeurs ES
GcpKmsSignerconstructeur : GcpKmsConfig, cert DER, chaîne DER, client PSR-18, fabriques PSR-17, journaliseur PSR-3l’algorithme par défaut est GcpKmsSigningAlgorithm::RsaSignPkcs1_2048Sha256voir les méthodesfinal ; 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, journaliseurconstruit GcpKmsConfig::fromEnvironment() lorsque $config vaut nullselfL’acquisition du jeton bearer est déléguée à l’appelant
GcpKmsSigner::withAlgorithm()GcpKmsSigningAlgorithm $algorithmAperçu au moment de la configuration uniquement ; le nom filaire par appel l’emporte au moment de la signatureselfLa taille de clé est fixée par la CryptoKeyVersion provisionnée
AwsKmsSigningStrategyconstructeur : AwsKmsSigner $signerSynchrone ; isAsync() retourne falsePropage les exceptions du signataire encapsuléAdaptateur pour RemoteSigningSession::complete()
AzureKeyVaultSigningStrategyconstructeur : AzureKeyVaultSigner $signerSynchrone ; isAsync() retourne falsePropage les exceptions du signataire encapsuléAdaptateur pour RemoteSigningSession::complete()
KmsSigningAlgorithmenum, 9 cas (RSA PKCS#1, RSA-PSS, ECDSA ; SHA-256/384/512)valeurs filaires SigningAlgorithm d’AWS KMSInvalidArgumentException depuis fromOpenSslName()resolveForWireName() préserve le condensé PSS configuré
AzureSigningAlgorithmenum, 9 cas (RS256ES512)valeurs de style JWA d’Azure Key VaultInvalidArgumentException depuis fromOpenSslName()isEcdsa() marque les valeurs dont la sortie nécessite une conversion DER
GcpKmsSigningAlgorithmenum, 10 cas (EC P-256/P-384, RSA PKCS#1, RSA-PSS)valeurs d’algorithme CryptoKeyVersion de GCPUnsupportedAlgorithmException depuis fromOpenSslName()La résolution du nom filaire choisit la plus petite taille de clé correspondante
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'): string
public 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): self
public 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): self
public function __construct(
private AwsKmsSigner $signer,
) {}
public function sign(string $signedAttributesDer): string
public function __construct(
private AzureKeyVaultSigner $signer,
) {}
public function sign(string $signedAttributesDer): string

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.

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é.

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.

FournisseurVersion de clé nullChaîne videGrammaire de remplacement
AwsKmsSignerUtilise AwsKmsConfig::$keyId ; un alias ou un ARN se résout vers la clé courante côté fournisseurRejetéeUUID (avec ou sans tirets), alias/<name>, ou un ARN de clé/alias KMS
AzureKeyVaultSignerUtilise la version de clé configurée ; une valeur de configuration vide sélectionne côté serveur la dernière version activéeRejetéeIdentifiant hexadécimal de 32 caractères
GcpKmsSignerUtilise la version épinglée dans GcpKmsConfig ; si aucune n’est épinglée, lève KeyManagementExceptionRejetéeIdentifiant 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.

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é.

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.

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.

  • Une version de clé sous forme de chaîne vide est rejetée sur les trois fournisseurs. Passe null pour 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.
  • AwsKmsSigner avec un AwsKmsConfig::$keyId vide et une version de clé null lève KeyManagementException.
  • Les réponses du fournisseur qui indiquent un échec de gestion de clé se mappent à KeyManagementException : AWS NotFoundException, DisabledException, KeyUnavailableException, InvalidKeyUsageException, ou HTTP 404 ; Azure HTTP 404, KeyNotFound, KeyDisabled, ou KeyNotActive ; 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 SignatureFailedException sur AWS et GCP, et AzureKeyVaultException sur 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.
  • AzureKeyVaultSigner sans jeton d’accès ni identifiants de principal de service lève AzureKeyVaultException avant tout appel au coffre. Une acquisition de jeton Azure AD ayant échoué lève également AzureKeyVaultException.
  • AzureKeyVaultSigner valide 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 avec AzureKeyVaultException.
  • GcpKmsSigner sans jeton bearer OAuth2 lève SignatureFailedException ; 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 champ value manquant lève AzureKeyVaultException).
  • Un champ de signature du fournisseur dont le décodage base64 échoue lève SignatureFailedException sur AWS et GCP, et AzureKeyVaultException sur Azure.
  • Aucun adaptateur SigningStrategy pour GcpKmsSigner n’est livré dans la 3.1.0. Le signataire GCP est consommé directement via le contrat KmsSignerInterface.

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.

RevendicationNormeClause
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 3161Appendix 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.

  • Disponibilité au sein du package Pro : AwsKmsSigner depuis la 1.9.0, AzureKeyVaultSigner depuis la 2.0.0, GcpKmsSigner et KmsSignerInterface depuis la 2.1.0. Tous sont à jour dans nextpdf/pro 3.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 KmsSignerInterface et doivent placer leur providerId() dans un espace de noms afin d’éviter les collisions avec les identifiants intégrés réservés.

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.