Pro edizione
Firma con Cloud KMS — Riferimento approfondito
In sintesi
Sezione intitolata “In sintesi”Questa pagina è il riferimento a livello di contratto per la superficie di firma cloud-KMS di NextPDF Pro. La superficie è composta da una Service Provider Interface, NextPDF\Pro\Security\Signing\Kms\KmsSignerInterface, e da tre signer per provider: AwsKmsSigner, AzureKeyVaultSigner e GcpKmsSigner. Due adapter, AwsKmsSigningStrategy e AzureKeyVaultSigningStrategy, collegano un signer al contratto SigningStrategy di Pro. Ogni signer invia al proprio provider solo un message digest tramite HTTP PSR-18. La chiave privata e il documento non attraversano mai il confine. Questa pagina espone l’API pubblica, il contratto di comportamento osservabile e le modalità di errore tipizzate. L’orchestrazione delle sessioni (RemoteSigningSession, SequentialSigner) e la marcatura temporale (PadesBtTimestamper) risiedono nelle rispettive pagine.
Disponibilità e licenze
Sezione intitolata “Disponibilità e licenze”Questa capacità è distribuita in NextPDF Pro (nextpdf/pro) e si attiva con un envelope di licenza di tier Pro. Un deployment privo di tale entitlement non carica le classi della capacità. Confronta le edizioni e ottieni una licenza.
Superficie dell’API pubblica
Sezione intitolata “Superficie dell’API pubblica”| Simbolo | Parametri | Comportamento predefinito | Restituisce | Solleva o fallisce con | Note |
|---|---|---|---|---|---|
KmsSignerInterface | — | Estende il contratto Core HsmSignerInterface | — | — | SPI per driver KMS e HSM; id integrati riservati: aws-kms, azure-keyvault, gcp-kms, pkcs11, openssl-cli |
KmsSignerInterface::providerId() | nessuno | Chiave stabile di lookup nel registry | non-empty-string | — | I driver di terze parti devono usare un namespace per il proprio identificatore |
KmsSignerInterface::signWithVersion() | $data, $algorithm = 'sha256WithRSAEncryption', $keyVersion = null | Una versione della chiave null ricade sul default del provider | string ottetti di firma: RSA come restituita dal provider (collocata direttamente in SignerInfo.signature), ECDSA come ECDSA-Sig-Value DER secondo le regole CMS | KeyManagementException, UnsupportedAlgorithmException, SignatureFailedException | La semantica di null per provider differisce; vedere il contratto di comportamento |
KmsSignerInterface::supportsAlgorithm() | string $algorithm | Sonda di capacità; non esegue alcun I/O | bool | — | Chiamata prima della selezione del provider |
KmsSignerInterface::supportedAlgorithms() | nessuno | Elenca i nomi in stile OpenSSL accettati dal provider | list<non-empty-string> | — | — |
AwsKmsSigner | costruttore: AwsKmsConfig, cert DER, chain DER, client PSR-18, factory PSR-17, logger PSR-3 | L’algoritmo predefinito è KmsSigningAlgorithm::RsaPkcs1Sha256 | — | vedere i metodi | final; PROVIDER_ID = 'aws-kms' |
AwsKmsSigner::create() | key id, cert DER, dipendenze PSR, chain opzionale, config, logger | Costruisce AwsKmsConfig::fromEnvironment($keyId) quando $config è null | self | — | Legge le variabili d’ambiente standard AWS_* |
AwsKmsSigner::withAlgorithm() | KmsSigningAlgorithm $algorithm | Restituisce un clone modificato | self | — | Deve corrispondere al tipo di chiave provisionata in AWS KMS |
AwsKmsSigner::sign() | $data, $algorithm = 'sha256WithRSAEncryption' | Delega a signWithVersion($data, $algorithm, null) | string | come signWithVersion() | Percorso legacy del contratto Core a due argomenti |
AzureKeyVaultSigner | costruttore: AzureKeyVaultConfig, cert DER, chain DER, client PSR-18, factory PSR-17, logger PSR-3 | L’algoritmo predefinito è AzureSigningAlgorithm::Rs256; un access token di config inizializza il bearer token | — | vedere i metodi | final; PROVIDER_ID = 'azure-keyvault' |
AzureKeyVaultSigner::create() | nome vault, nome chiave, cert DER, dipendenze PSR, chain opzionale, config, logger | Costruisce AzureKeyVaultConfig::fromEnvironment() quando $config è null | self | — | Supporta token pre-ottenuto o credenziali service-principal |
AzureKeyVaultSigner::withAlgorithm() | AzureSigningAlgorithm $algorithm | Restituisce un clone modificato | self | — | Le chiavi RSA usano valori RS/PS; le chiavi EC usano valori ES |
GcpKmsSigner | costruttore: GcpKmsConfig, cert DER, chain DER, client PSR-18, factory PSR-17, logger PSR-3 | L’algoritmo predefinito è GcpKmsSigningAlgorithm::RsaSignPkcs1_2048Sha256 | — | vedere i metodi | final; PROVIDER_ID = 'gcp-kms', API_VERSION = 'v1' |
GcpKmsSigner::create() | project id, location, key ring, crypto key, cert DER, dipendenze PSR, chain opzionale, config, logger | Costruisce GcpKmsConfig::fromEnvironment() quando $config è null | self | — | L’acquisizione del bearer token è delegata al chiamante |
GcpKmsSigner::withAlgorithm() | GcpKmsSigningAlgorithm $algorithm | Solo anteprima al tempo di config; il nome di wire per chiamata prevale al momento della firma | self | — | La dimensione della chiave è fissata dalla CryptoKeyVersion provisionata |
AwsKmsSigningStrategy | costruttore: AwsKmsSigner $signer | Sincrono; isAsync() restituisce false | — | Propaga le eccezioni del signer incapsulato | Adapter per RemoteSigningSession::complete() |
AzureKeyVaultSigningStrategy | costruttore: AzureKeyVaultSigner $signer | Sincrono; isAsync() restituisce false | — | Propaga le eccezioni del signer incapsulato | Adapter per RemoteSigningSession::complete() |
KmsSigningAlgorithm | enum, 9 casi (RSA PKCS#1, RSA-PSS, ECDSA; SHA-256/384/512) | — | Valori di wire SigningAlgorithm di AWS KMS | InvalidArgumentException da fromOpenSslName() | resolveForWireName() preserva il digest PSS configurato |
AzureSigningAlgorithm | enum, 9 casi (RS256…ES512) | — | Valori in stile JWA di Azure Key Vault | InvalidArgumentException da fromOpenSslName() | isEcdsa() contrassegna i valori il cui output richiede conversione DER |
GcpKmsSigningAlgorithm | enum, 10 casi (EC P-256/P-384, RSA PKCS#1, RSA-PSS) | — | Valori di algoritmo CryptoKeyVersion di GCP | UnsupportedAlgorithmException da fromOpenSslName() | La risoluzione del nome di wire sceglie la più piccola dimensione di chiave corrispondente |
Firme dei punti di ingresso
Sezione intitolata “Firme dei punti di ingresso”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): stringContratto di comportamento
Sezione intitolata “Contratto di comportamento”Risoluzione del contratto
Sezione intitolata “Risoluzione del contratto”KmsSignerInterface estende il contratto Core HsmSignerInterface. Aggiunge providerId(), il signWithVersion() consapevole della versione della chiave, e le sonde di capacità supportsAlgorithm() e supportedAlgorithms(). Il sign() ereditato a due argomenti delega a signWithVersion() con una versione della chiave null su tutti e tre i signer. getCertificateDer(), getCertificateChainDer() e getPublicKeyAlgorithm() sono implementati a partire dal materiale fornito dal costruttore. Le sonde di capacità non eseguono alcun I/O. Ogni signer espone inoltre gli accessor getSigningAlgorithm() e getConfig() a fini di ispezione.
Trasmissione del solo digest
Sezione intitolata “Trasmissione del solo digest”Ogni signer esegue localmente l’hash di $data con il digest dell’algoritmo risolto e trasmette solo quel digest. AWS riceve un digest in base64 con MessageType: DIGEST. Azure riceve un digest in base64url nel corpo della sign request. GCP riceve un digest in base64 nel campo digest specifico dell’algoritmo. I byte del documento non compaiono mai in una request al provider. Tutto il trasporto usa un client HTTP PSR-18 standard sull’endpoint HTTPS del provider; non è coinvolto alcun SDK del vendor cloud.
Risoluzione della versione della chiave
Sezione intitolata “Risoluzione della versione della chiave”signWithVersion() valida l’argomento della versione della chiave in modalità fail-closed prima che venga costruita qualsiasi request. Un valore che non supera la grammatica del provider solleva KeyManagementException e previene l’injection nel segmento di URL o nel KeyId.
| Provider | Versione della chiave null | Stringa vuota | Grammatica di override |
|---|---|---|---|
AwsKmsSigner | Usa AwsKmsConfig::$keyId; un alias o un ARN si risolve nella chiave corrente lato provider | Rifiutata | UUID (con o senza trattini), alias/<name>, o un ARN di chiave/alias KMS |
AzureKeyVaultSigner | Usa la versione della chiave configurata; un valore di config vuoto seleziona lato server l’ultima versione abilitata | Rifiutata | Identificatore esadecimale di 32 caratteri |
GcpKmsSigner | Usa la versione pinnata in GcpKmsConfig; se nessuna è pinnata, solleva KeyManagementException | Rifiutata | Id decimale di CryptoKeyVersion, sole cifre |
GCP non ha una primitiva lato server per la “versione attiva”. L’endpoint asymmetric-sign opera solo su una specifica risorsa cryptoKeyVersions/{n}, quindi una versione deve sempre essere risolvibile.
Risoluzione dell’algoritmo
Sezione intitolata “Risoluzione dell’algoritmo”Il livello strategy inoltra un nome di wire in stile OpenSSL. AWS e Azure accettano sette nomi di wire (PKCS#1 ed ECDSA a SHA-256/384/512, più RSASSA-PSS). GCP ne accetta cinque (sha256WithRSAEncryption, sha512WithRSAEncryption, RSASSA-PSS, ecdsa-with-SHA256, ecdsa-with-SHA384). Il nome di wire RSASSA-PSS non codifica un digest, quindi è ambiguo rispetto al digest. AwsKmsSigner lo risolve tramite KmsSigningAlgorithm::resolveForWireName(), che preserva il digest della variante PSS configurata. AzureKeyVaultSigner si affida alla variante PSS configurata per il nome ambiguo. Solleva UnsupportedAlgorithmException se un digest PSS risolto divergesse da quello configurato. GcpKmsSigner ri-risolve l’enum dal nome di wire a ogni chiamata; withAlgorithm() su GCP è un’anteprima al tempo di config e non modifica il comportamento al momento della firma. Un nome di wire non supportato solleva UnsupportedAlgorithmException prima di qualsiasi chiamata di rete. Su AwsKmsSigner e GcpKmsSigner, una sign call aggiorna il valore riportato successivamente da getSigningAlgorithm() all’algoritmo risolto per quella chiamata. Su AzureKeyVaultSigner, la risoluzione è locale alla chiamata e il valore configurato resta autorevole.
Normalizzazione della firma
Sezione intitolata “Normalizzazione della firma”AWS e GCP restituiscono le firme nella forma che il CMS consuma: gli ottetti di firma RSA finiscono in SignerInfo.signature invariati, e l’ECDSA arriva codificata in DER. Azure restituisce l’ECDSA in forma raw IEEE P1363 (r||s), che il signer converte in un ECDSA-Sig-Value DER prima di restituirla.
Integrazione CMS e adiacenza
Sezione intitolata “Integrazione CMS e adiacenza”Un adapter SigningStrategy firma gli attributi firmati codificati in DER forniti dalla sessione. In presenza di attributi firmati, l’input di firma CMS è il digest dell’intera codifica DER del valore SignedAttrs — RFC 5652 §5.4. I metodi getSignatureAlgorithmOid() e getDigestAlgorithm() dell’adapter alimentano i campi signatureAlgorithm e digestAlgorithm del SignerInfo — RFC 5652 §5.3. I byte restituiti diventano la OCTET STRING della firma del SignerInfo — RFC 5652 §5.5. L’assemblaggio CMS, la gestione di ByteRange e il ciclo di vita della sessione appartengono a RemoteSigningSession; i flussi multi-parte appartengono a SequentialSigner. Una signature-time-stamp PAdES B-T, il cui messageImprint esegue l’hash del valore di firma del SignerInfo — RFC 3161 Appendix A — è applicata da PadesBtTimestamper, non da questi signer. Tutti e tre sono documentati nel riferimento approfondito sulla sicurezza di Pro.
Casi limite e modalità di errore
Sezione intitolata “Casi limite e modalità di errore”- Una versione della chiave a stringa vuota è rifiutata su tutti e tre i provider. Passare
nullper ereditare il default configurato. - Una versione della chiave malformata è rifiutata prima che venga costruita qualsiasi request, con il valore incriminato indicato nell’eccezione.
AwsKmsSignercon unAwsKmsConfig::$keyIdvuoto e una versione della chiavenullsollevaKeyManagementException.- Le risposte del provider che indicano un fallimento di key-management si mappano a
KeyManagementException: AWSNotFoundException,DisabledException,KeyUnavailableException,InvalidKeyUsageException, o HTTP 404; Azure HTTP 404,KeyNotFound,KeyDisabled, oKeyNotActive; GCP HTTP 404 o 409,NOT_FOUND,FAILED_PRECONDITION, o un HTTP 400 il cui messaggio nomina una versione. - Altre risposte del provider diverse da 200 sollevano
SignatureFailedExceptionsu AWS e GCP, eAzureKeyVaultExceptionsu Azure. - Un fallimento di trasporto PSR-18 durante la firma si mappa a
SignatureFailedExceptioncon l’eccezione del client preservata come throwable precedente. AzureKeyVaultSignersenza access token e senza credenziali service-principal sollevaAzureKeyVaultExceptionprima di qualsiasi chiamata al vault. Anche un’acquisizione fallita del token Azure AD sollevaAzureKeyVaultException.AzureKeyVaultSignervalida il nome del vault, il nome della chiave, la versione della chiave e il tenant id rispetto alle grammatiche pubblicate da Azure nel chokepoint della request. Un valore che contiene caratteri strutturali di URL fallisce in modo fail-closed conAzureKeyVaultException.GcpKmsSignersenza un bearer token OAuth2 sollevaSignatureFailedException; l’acquisizione del token è responsabilità del chiamante.- Una risposta del provider che non è JSON valido, o a cui manca il campo della firma, solleva
SignatureFailedException(Azure: un campovaluemancante sollevaAzureKeyVaultException). - Un campo di firma del provider che non supera la decodifica base64 solleva
SignatureFailedExceptionsu AWS e GCP, eAzureKeyVaultExceptionsu Azure. - Nessun adapter
SigningStrategyperGcpKmsSignerè distribuito nella 3.1.0. Il signer GCP è consumato direttamente tramite il contrattoKmsSignerInterface.
Comportamento in modalità FIPS
Sezione intitolata “Comportamento in modalità FIPS”AwsKmsConfig::withFipsEndpoint() instrada le request all’endpoint kms-fips della regione. Lo stato di validazione FIPS di quell’endpoint è una proprietà di AWS, non di NextPDF. AzureKeyVaultConfig e GcpKmsConfig non espongono alcun helper dedicato per l’endpoint FIPS nella 3.1.0. Il calcolo del digest viene eseguito in-process con la funzione PHP hash() e non è di per sé un modulo validato. NextPDF Pro può operare contro un confine KMS o HSM validato FIPS, ma NextPDF non è un modulo crittografico validato FIPS e non avanza alcuna rivendicazione di certificazione FIPS.
Conformità
Sezione intitolata “Conformità”| Rivendicazione | Standard | Clausola |
|---|---|---|
| La strategy firma gli attributi firmati codificati in DER; il digest di input della firma CMS copre l’intera codifica DER di SignedAttrs. | RFC 5652 | §5.4 |
| Gli SignedAttributes sono codificati in DER e contengono almeno content-type e message-digest; signatureAlgorithm identifica l’algoritmo del signer. | RFC 5652 | §5.3 |
| I byte di firma restituiti sono codificati come OCTET STRING e trasportati nel campo signature del SignerInfo. | RFC 5652 | §5.5 |
| Il messageImprint di una signature time-stamp esegue l’hash del valore di firma del SignerInfo (superficie B-T adiacente, non questi signer). | RFC 3161 | Appendix A |
Tutte le clausole sono parafrasate; NextPDF non riproduce il testo normativo. Si tratta di dichiarazioni di capacità, non di certificazioni. NextPDF non detiene alcuna certificazione e non ne concede alcuna. Se una firma prodotta verifichi è una decisione del verificatore rispetto ai propri trust anchor e alla propria policy; i signer restituiscono i byte di firma e non asseriscono alcun esito attendibile. La custodia della chiave, la protezione della chiave e la validazione dell’algoritmo lato provider sono proprietà del KMS configurato, non di NextPDF.
Note di sviluppo
Sezione intitolata “Note di sviluppo”- Disponibilità all’interno del package Pro:
AwsKmsSignerdalla 1.9.0,AzureKeyVaultSignerdalla 2.0.0,GcpKmsSignereKmsSignerInterfacedalla 2.1.0. Tutti sono attuali innextpdf/pro3.1.0. - I signer dipendono solo da PSR-18, PSR-17 e PSR-3. Non è richiesto né incluso alcun SDK AWS, Azure o Google.
- Sondare
supportsAlgorithm()prima di firmare, così che un provider incompatibile venga rifiutato al momento della selezione, non a metà sessione. - I campi delle credenziali sono iniettati dal costruttore e contrassegnati come parametri sensibili. I messaggi di log contengono solo campi strutturali; nessuna credenziale, token o contenuto del documento viene scritto nei log.
- Pinnare esplicitamente le versioni delle chiavi nei deployment regolamentati. I default di risoluzione dell’alias (AWS) e dell’ultima versione abilitata (Azure) sono comodi ma non deterministici tra una rotazione e l’altra.
- I driver di terze parti implementano
KmsSignerInterfacee devono usare un namespace per il proprioproviderId()per evitare collisioni con gli identificatori integrati riservati.
Vedere anche
Sezione intitolata “Vedere anche”- Firma con Cloud KMS (capacità) — la pagina how-to: setup, configurazione e il confine di custodia della chiave.
- Sicurezza — Riferimento approfondito —
RemoteSigningSession,SequentialSigner, la superficie PAdES B-B/B-T e il contrattoSigningStrategy. - Firma — Riferimento approfondito (Enterprise) — il confine del produttore a lungo termine B-LT/B-LTA.
- Sicurezza / Firma (Core) — il signer CMS Core e i contratti che questa superficie estende.
Confine di pubblicazione
Sezione intitolata “Confine di pubblicazione”Questa pagina documenta solo il comportamento osservabile esternamente e la superficie dell’API pubblica supportata. I percorsi di namespace interni, le classi helper, le tabelle dei meccanismi, i nomi dei file di runbook e i prefissi dei ticket sono fuori ambito.