Ga naar inhoud
getnextpdf.com

Pro editie

Cloud KMS-ondertekening — Diepe referentie

Deze pagina is de referentie op contractniveau voor het cloud-KMS-ondertekeningsoppervlak van NextPDF Pro. Het oppervlak bestaat uit één Service Provider Interface, NextPDF\Pro\Security\Signing\Kms\KmsSignerInterface, en drie provider-signers: AwsKmsSigner, AzureKeyVaultSigner en GcpKmsSigner. Twee adapters, AwsKmsSigningStrategy en AzureKeyVaultSigningStrategy, verbinden een signer met het Pro SigningStrategy-contract. Elke signer stuurt alleen een message digest naar zijn provider over PSR-18 HTTP. De private sleutel en het document overschrijden de grens nooit. Deze pagina beschrijft de publieke API, het waarneembare gedragscontract en de getypeerde faalmodi. Sessie-orkestratie (RemoteSigningSession, SequentialSigner) en timestamping (PadesBtTimestamper) staan op hun eigen pagina’s.

Deze mogelijkheid wordt geleverd in NextPDF Pro (nextpdf/pro) en wordt geactiveerd met een licentie-envelop op Pro-niveau. Een deployment zonder die entitlement laadt de klassen van de mogelijkheid niet. Vergelijk edities en verkrijg een licentie.

SymboolParametersStandaardgedragRetourneertGooit of faalt metOpmerkingen
KmsSignerInterfaceBreidt het Core HsmSignerInterface-contract uitSPI voor KMS- en HSM-drivers; gereserveerde ingebouwde ids: aws-kms, azure-keyvault, gcp-kms, pkcs11, openssl-cli
KmsSignerInterface::providerId()noneStabiele opzoeksleutel voor het registernon-empty-stringDrivers van derden moeten hun identifier namespacen
KmsSignerInterface::signWithVersion()$data, $algorithm = 'sha256WithRSAEncryption', $keyVersion = nullnull-sleutelversie valt terug op de provider-standaardstring handtekening-octets: RSA zoals geretourneerd door de provider (rechtstreeks geplaatst in SignerInfo.signature), ECDSA als DER ECDSA-Sig-Value volgens CMS-regelsKeyManagementException, UnsupportedAlgorithmException, SignatureFailedExceptionnull-semantiek verschilt per provider; zie het gedragscontract
KmsSignerInterface::supportsAlgorithm()string $algorithmCapability-probe; voert geen I/O uitboolAangeroepen vóór providerselectie
KmsSignerInterface::supportedAlgorithms()noneSomt de OpenSSL-stijl namen op die de provider accepteertlist<non-empty-string>
AwsKmsSignerconstructor: AwsKmsConfig, cert DER, chain DER, PSR-18 client, PSR-17 factories, PSR-3 loggerAlgoritme standaard op KmsSigningAlgorithm::RsaPkcs1Sha256zie methodenfinal; PROVIDER_ID = 'aws-kms'
AwsKmsSigner::create()key id, cert DER, PSR-afhankelijkheden, optionele chain, config, loggerBouwt AwsKmsConfig::fromEnvironment($keyId) wanneer $config null isselfLeest de standaard AWS_*-omgevingsvariabelen
AwsKmsSigner::withAlgorithm()KmsSigningAlgorithm $algorithmRetourneert een aangepaste kloonselfMoet overeenkomen met het sleuteltype dat in AWS KMS is voorzien
AwsKmsSigner::sign()$data, $algorithm = 'sha256WithRSAEncryption'Delegeert aan signWithVersion($data, $algorithm, null)stringzoals signWithVersion()Legacy pad van het twee-argument-Core-contract
AzureKeyVaultSignerconstructor: AzureKeyVaultConfig, cert DER, chain DER, PSR-18 client, PSR-17 factories, PSR-3 loggerAlgoritme standaard op AzureSigningAlgorithm::Rs256; een config-accesstoken initieert het bearer-tokenzie methodenfinal; PROVIDER_ID = 'azure-keyvault'
AzureKeyVaultSigner::create()vault-naam, key-naam, cert DER, PSR-afhankelijkheden, optionele chain, config, loggerBouwt AzureKeyVaultConfig::fromEnvironment() wanneer $config null isselfOndersteunt vooraf verkregen token of service-principal-credentials
AzureKeyVaultSigner::withAlgorithm()AzureSigningAlgorithm $algorithmRetourneert een aangepaste kloonselfRSA-sleutels gebruiken RS/PS-waarden; EC-sleutels gebruiken ES-waarden
GcpKmsSignerconstructor: GcpKmsConfig, cert DER, chain DER, PSR-18 client, PSR-17 factories, PSR-3 loggerAlgoritme standaard op GcpKmsSigningAlgorithm::RsaSignPkcs1_2048Sha256zie methodenfinal; PROVIDER_ID = 'gcp-kms', API_VERSION = 'v1'
GcpKmsSigner::create()project id, locatie, key ring, crypto key, cert DER, PSR-afhankelijkheden, optionele chain, config, loggerBouwt GcpKmsConfig::fromEnvironment() wanneer $config null isselfHet verkrijgen van een bearer-token wordt aan de aanroeper gedelegeerd
GcpKmsSigner::withAlgorithm()GcpKmsSigningAlgorithm $algorithmAlleen preview op config-tijd; de wire-naam per aanroep wint op sign-tijdselfDe sleutelgrootte ligt vast door de voorziene CryptoKeyVersion
AwsKmsSigningStrategyconstructor: AwsKmsSigner $signerSynchroon; isAsync() retourneert falseGeeft de excepties van de omhulde signer doorAdapter voor RemoteSigningSession::complete()
AzureKeyVaultSigningStrategyconstructor: AzureKeyVaultSigner $signerSynchroon; isAsync() retourneert falseGeeft de excepties van de omhulde signer doorAdapter voor RemoteSigningSession::complete()
KmsSigningAlgorithmenum, 9 cases (RSA PKCS#1, RSA-PSS, ECDSA; SHA-256/384/512)AWS KMS SigningAlgorithm-wire-waardenInvalidArgumentException van fromOpenSslName()resolveForWireName() behoudt de geconfigureerde PSS-digest
AzureSigningAlgorithmenum, 9 cases (RS256ES512)Azure Key Vault JWA-stijl waardenInvalidArgumentException van fromOpenSslName()isEcdsa() markeert waarden waarvan de uitvoer DER-conversie nodig heeft
GcpKmsSigningAlgorithmenum, 10 cases (EC P-256/P-384, RSA PKCS#1, RSA-PSS)GCP CryptoKeyVersion-algoritmewaardenUnsupportedAlgorithmException van fromOpenSslName()Wire-naam-resolutie kiest de kleinste passende sleutelgrootte
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 breidt het Core HsmSignerInterface-contract uit. Het voegt providerId(), het key-version-bewuste signWithVersion() en de capability-probes supportsAlgorithm() en supportedAlgorithms() toe. Het overgeërfde twee-argument-sign() delegeert op alle drie de signers aan signWithVersion() met een null-sleutelversie. getCertificateDer(), getCertificateChainDer() en getPublicKeyAlgorithm() worden geïmplementeerd op basis van het via de constructor aangeleverde materiaal. Capability-probes voeren geen I/O uit. Elke signer stelt ook getSigningAlgorithm()- en getConfig()-accessors beschikbaar voor inspectie.

Elke signer hasht $data lokaal met de digest van het opgeloste algoritme en verzendt alleen die digest. AWS ontvangt een base64-digest met MessageType: DIGEST. Azure ontvangt een base64url-digest in de body van het sign-request. GCP ontvangt een base64-digest in het algoritmespecifieke digest-veld. De documentbytes verschijnen nooit in een provider-request. Al het transport gebruikt een standaard PSR-18 HTTP client over het HTTPS-endpoint van de provider; er is geen cloud-vendor-SDK bij betrokken.

signWithVersion() valideert het sleutelversie-argument fail-closed voordat er een request wordt opgebouwd. Een waarde die niet aan de provider-grammatica voldoet, gooit KeyManagementException en voorkomt injectie in een URL-segment of KeyId.

Providernull-sleutelversieLege stringOverride-grammatica
AwsKmsSignerGebruikt AwsKmsConfig::$keyId; een alias of ARN wordt aan de providerkant tot de huidige sleutel opgelostGeweigerdUUID (met of zonder streepjes), alias/<name>, of een KMS key/alias-ARN
AzureKeyVaultSignerGebruikt de geconfigureerde sleutelversie; een lege config-waarde selecteert de laatste ingeschakelde versie aan serverkantGeweigerd32-teken hexadecimale identifier
GcpKmsSignerGebruikt de in GcpKmsConfig vastgezette versie; met geen enkele vastgezet, gooit KeyManagementExceptionGeweigerdDecimale CryptoKeyVersion-id, alleen cijfers

GCP kent geen server-side “actieve versie”-primitief. Het asymmetric-sign-endpoint werkt uitsluitend op een specifieke cryptoKeyVersions/{n}-resource, dus een versie moet altijd oplosbaar zijn.

De strategielaag geeft een OpenSSL-stijl wire-naam door. AWS en Azure accepteren zeven wire-namen (PKCS#1 en ECDSA bij SHA-256/384/512, plus RSASSA-PSS). GCP accepteert er vijf (sha256WithRSAEncryption, sha512WithRSAEncryption, RSASSA-PSS, ecdsa-with-SHA256, ecdsa-with-SHA384). De RSASSA-PSS-wire-naam codeert geen digest, dus is hij digest-ambigu. AwsKmsSigner lost hem op via KmsSigningAlgorithm::resolveForWireName(), dat de digest van de geconfigureerde PSS-variant behoudt. AzureKeyVaultSigner vertrouwt voor de ambigue naam op de geconfigureerde PSS-variant. Het gooit UnsupportedAlgorithmException als een opgeloste PSS-digest zou afwijken van de geconfigureerde. GcpKmsSigner lost de enum bij elke aanroep opnieuw op uit de wire-naam; withAlgorithm() op GCP is een preview op config-tijd en verandert het gedrag op sign-tijd niet. Een niet-ondersteunde wire-naam gooit UnsupportedAlgorithmException vóór elke netwerkaanroep. Op AwsKmsSigner en GcpKmsSigner werkt een sign-aanroep de waarde bij die later door getSigningAlgorithm() wordt gerapporteerd, naar het per aanroep opgeloste algoritme. Op AzureKeyVaultSigner is de resolutie aanroeplokaal en blijft de geconfigureerde waarde gezaghebbend.

AWS en GCP retourneren handtekeningen in de vorm die CMS verbruikt: RSA-handtekening-octets gaan ongewijzigd in SignerInfo.signature, en ECDSA arriveert DER-gecodeerd. Azure retourneert ECDSA in ruwe IEEE P1363-vorm (r||s), die de signer vóór het retourneren omzet naar een DER ECDSA-Sig-Value.

Een SigningStrategy-adapter ondertekent de DER-gecodeerde signed attributes die door de sessie worden aangeleverd. Met signed attributes aanwezig is de CMS-handtekeninginvoer de digest van de complete DER-codering van de SignedAttrs-waarde — RFC 5652 §5.4. De getSignatureAlgorithmOid() en getDigestAlgorithm() van de adapter voeden de SignerInfo-velden signatureAlgorithm en digestAlgorithm — RFC 5652 §5.3. De geretourneerde bytes worden de SignerInfo signature OCTET STRING — RFC 5652 §5.5. CMS-assemblage, ByteRange-afhandeling en de sessielevenscyclus behoren tot RemoteSigningSession; multi-party-flows behoren tot SequentialSigner. Een PAdES B-T signature-time-stamp, waarvan de messageImprint de SignerInfo-handtekeningwaarde hasht — RFC 3161 Appendix A — wordt toegepast door PadesBtTimestamper, niet door deze signers. Alle drie zijn gedocumenteerd op de Pro security diepgaande referentie.

  • Een lege-string-sleutelversie wordt op alle drie de providers geweigerd. Geef null door om de geconfigureerde standaard over te nemen.
  • Een misvormde sleutelversie wordt geweigerd voordat er een request wordt opgebouwd, met de overtredende waarde benoemd in de exceptie.
  • AwsKmsSigner met een lege AwsKmsConfig::$keyId en een null-sleutelversie gooit KeyManagementException.
  • Provider-responses die op een key-management-fout wijzen, worden gemapt naar KeyManagementException: AWS NotFoundException, DisabledException, KeyUnavailableException, InvalidKeyUsageException, of HTTP 404; Azure HTTP 404, KeyNotFound, KeyDisabled, of KeyNotActive; GCP HTTP 404 of 409, NOT_FOUND, FAILED_PRECONDITION, of een HTTP 400 waarvan het bericht een versie benoemt.
  • Andere niet-200-provider-responses gooien SignatureFailedException op AWS en GCP, en AzureKeyVaultException op Azure.
  • Een PSR-18-transportfout tijdens het ondertekenen wordt gemapt naar SignatureFailedException met de client-exceptie bewaard als de vorige throwable.
  • AzureKeyVaultSigner zonder access token en zonder service-principal-credentials gooit AzureKeyVaultException vóór elke vault-aanroep. Een mislukte Azure AD-tokenverkrijging gooit eveneens AzureKeyVaultException.
  • AzureKeyVaultSigner valideert de vault-naam, key-naam, sleutelversie en tenant id tegen de gepubliceerde grammatica’s van Azure bij het request-chokepoint. Een waarde die URL-structurele tekens draagt, faalt closed met AzureKeyVaultException.
  • GcpKmsSigner zonder OAuth2-bearer-token gooit SignatureFailedException; tokenverkrijging is de verantwoordelijkheid van de aanroeper.
  • Een provider-response die geen geldige JSON is, of die het signature-veld mist, gooit SignatureFailedException (Azure: een ontbrekend value-veld gooit AzureKeyVaultException).
  • Een provider-signature-veld dat faalt bij base64-decodering gooit SignatureFailedException op AWS en GCP, en AzureKeyVaultException op Azure.
  • In 3.1.0 wordt geen SigningStrategy-adapter voor GcpKmsSigner geleverd. De GCP-signer wordt rechtstreeks via het KmsSignerInterface-contract gebruikt.

AwsKmsConfig::withFipsEndpoint() routeert requests naar het kms-fips-endpoint van de regio. De FIPS-validatiestatus van dat endpoint is een eigenschap van AWS, niet van NextPDF. AzureKeyVaultConfig en GcpKmsConfig stellen in 3.1.0 geen speciale FIPS-endpoint-helper beschikbaar. Digest-berekening draait in-process met de PHP-functie hash() en is zelf geen gevalideerde module. NextPDF Pro kan tegen een FIPS-gevalideerde KMS- of HSM-grens werken, maar NextPDF is geen FIPS-gevalideerde cryptografische module en doet geen FIPS-certificeringsclaim.

ClaimStandaardClausule
De strategie ondertekent de DER-gecodeerde signed attributes; de CMS-handtekeninginvoer-digest dekt de complete DER-codering van SignedAttrs.RFC 5652§5.4
SignedAttributes zijn DER-gecodeerd en dragen minimaal content-type en message-digest; signatureAlgorithm identificeert het algoritme van de signer.RFC 5652§5.3
De geretourneerde handtekeningbytes worden gecodeerd als een OCTET STRING en gedragen in het SignerInfo signature-veld.RFC 5652§5.5
De messageImprint van een signature time-stamp hasht de SignerInfo-handtekeningwaarde (aangrenzend B-T-oppervlak, niet deze signers).RFC 3161Appendix A

Alle clausules zijn geparafraseerd; NextPDF reproduceert geen normatieve tekst. Dit zijn capability-verklaringen, geen certificeringen. NextPDF houdt geen certificering en verleent er geen. Of een geproduceerde handtekening verifieert, is de beslissing van de verifieerder tegen zijn eigen trust anchors en beleid; de signers retourneren handtekeningbytes en beweren geen vertrouwde uitkomst. Sleutelbewaring, sleutelbescherming en algoritmevalidatie aan providerkant zijn eigenschappen van de geconfigureerde KMS, niet van NextPDF.

  • Beschikbaarheid binnen het Pro-pakket: AwsKmsSigner sinds 1.9.0, AzureKeyVaultSigner sinds 2.0.0, GcpKmsSigner en KmsSignerInterface sinds 2.1.0. Alle zijn actueel in nextpdf/pro 3.1.0.
  • De signers zijn alleen afhankelijk van PSR-18, PSR-17 en PSR-3. Geen AWS-, Azure- of Google-SDK is vereist of gebundeld.
  • Probe supportsAlgorithm() vóór het ondertekenen, zodat een incompatibele provider bij de selectie wordt geweigerd, niet midden in een sessie.
  • Credential-velden worden via de constructor geïnjecteerd en gemarkeerd als sensitive parameters. Logberichten dragen alleen structurele velden; geen credential, token of documentinhoud wordt naar de logs geschreven.
  • Zet sleutelversies expliciet vast in gereguleerde deployments. De standaardwaarden voor alias-resolutie (AWS) en latest-enabled (Azure) zijn handig maar niet deterministisch over rotaties heen.
  • Drivers van derden implementeren KmsSignerInterface en moeten hun providerId() namespacen om botsingen met de gereserveerde ingebouwde identifiers te vermijden.

Deze pagina documenteert alleen het extern waarneembare gedrag en het ondersteunde publieke API-oppervlak. Interne namespace-paden, helper-klassen, mechanisme-tabellen, runbook-bestandsnamen en ticket-prefixen vallen buiten de scope.