Zum Inhalt springen
getnextpdf.com

Pro Edition

Cloud-KMS-Signierung — Ausführliche Referenz

Diese Seite ist die Referenz auf Vertragsebene für die Cloud-KMS-Signierungsschnittstelle von NextPDF Pro. Die Schnittstelle besteht aus einem Service Provider Interface, NextPDF\Pro\Security\Signing\Kms\KmsSignerInterface, und drei Anbieter-Signierern: AwsKmsSigner, AzureKeyVaultSigner und GcpKmsSigner. Zwei Adapter, AwsKmsSigningStrategy und AzureKeyVaultSigningStrategy, verbinden einen Signierer mit dem Pro-Vertrag SigningStrategy. Jeder Signierer sendet nur einen Message-Digest über PSR-18-HTTP an seinen Anbieter. Der private Schlüssel und das Dokument überschreiten die Grenze niemals. Diese Seite beschreibt die öffentliche API, den beobachtbaren Verhaltensvertrag und die typisierten Fehlermodi. Die Session-Orchestrierung (RemoteSigningSession, SequentialSigner) und die Zeitstempelung (PadesBtTimestamper) sind auf eigenen Seiten dokumentiert.

Diese Funktion wird mit NextPDF Pro (nextpdf/pro) ausgeliefert und aktiviert sich mit einem Lizenz-Envelope der Pro-Stufe. Eine Bereitstellung ohne diese Berechtigung lädt die Klassen der Funktion nicht. Editionen vergleichen und eine Lizenz erwerben.

SymbolParameterStandardverhaltenRückgabeWirft oder scheitert mitAnmerkungen
KmsSignerInterfaceErweitert den Core-Vertrag HsmSignerInterfaceSPI für KMS- und HSM-Treiber; reservierte eingebaute IDs: aws-kms, azure-keyvault, gcp-kms, pkcs11, openssl-cli
KmsSignerInterface::providerId()keineStabiler Registry-Lookup-Schlüsselnon-empty-stringDrittanbieter-Treiber müssen ihren Bezeichner mit einem Namensraum versehen
KmsSignerInterface::signWithVersion()$data, $algorithm = 'sha256WithRSAEncryption', $keyVersion = nullEine null-Schlüsselversion fällt auf den Anbieterstandard zurückstring Signatur-Oktette: RSA wie vom Anbieter zurückgegeben (direkt in SignerInfo.signature platziert), ECDSA als DER-ECDSA-Sig-Value gemäß CMS-RegelnKeyManagementException, UnsupportedAlgorithmException, SignatureFailedExceptionDie null-Semantik unterscheidet sich je Anbieter; siehe den Verhaltensvertrag
KmsSignerInterface::supportsAlgorithm()string $algorithmFähigkeitsprüfung; führt keine I/O ausboolWird vor der Anbieterauswahl aufgerufen
KmsSignerInterface::supportedAlgorithms()keineListet die OpenSSL-artigen Namen auf, die der Anbieter akzeptiertlist<non-empty-string>
AwsKmsSignerKonstruktor: AwsKmsConfig, Cert-DER, Chain-DER, PSR-18-Client, PSR-17-Factorys, PSR-3-LoggerAlgorithmus ist standardmäßig KmsSigningAlgorithm::RsaPkcs1Sha256siehe Methodenfinal; PROVIDER_ID = 'aws-kms'
AwsKmsSigner::create()Schlüssel-ID, Cert-DER, PSR-Abhängigkeiten, optionale Chain, Config, LoggerErstellt AwsKmsConfig::fromEnvironment($keyId), wenn $config null istselfLiest die üblichen AWS_*-Umgebungsvariablen
AwsKmsSigner::withAlgorithm()KmsSigningAlgorithm $algorithmGibt einen modifizierten Klon zurückselfMuss zum in AWS KMS bereitgestellten Schlüsseltyp passen
AwsKmsSigner::sign()$data, $algorithm = 'sha256WithRSAEncryption'Delegiert an signWithVersion($data, $algorithm, null)stringwie signWithVersion()Legacy-Pfad des Zwei-Argument-Core-Vertrags
AzureKeyVaultSignerKonstruktor: AzureKeyVaultConfig, Cert-DER, Chain-DER, PSR-18-Client, PSR-17-Factorys, PSR-3-LoggerAlgorithmus ist standardmäßig AzureSigningAlgorithm::Rs256; ein Access-Token aus der Config initialisiert das Bearer-Tokensiehe Methodenfinal; PROVIDER_ID = 'azure-keyvault'
AzureKeyVaultSigner::create()Vault-Name, Schlüsselname, Cert-DER, PSR-Abhängigkeiten, optionale Chain, Config, LoggerErstellt AzureKeyVaultConfig::fromEnvironment(), wenn $config null istselfUnterstützt ein vorab bezogenes Token oder Service-Principal-Anmeldedaten
AzureKeyVaultSigner::withAlgorithm()AzureSigningAlgorithm $algorithmGibt einen modifizierten Klon zurückselfRSA-Schlüssel verwenden RS/PS-Werte; EC-Schlüssel verwenden ES-Werte
GcpKmsSignerKonstruktor: GcpKmsConfig, Cert-DER, Chain-DER, PSR-18-Client, PSR-17-Factorys, PSR-3-LoggerAlgorithmus ist standardmäßig GcpKmsSigningAlgorithm::RsaSignPkcs1_2048Sha256siehe Methodenfinal; PROVIDER_ID = 'gcp-kms', API_VERSION = 'v1'
GcpKmsSigner::create()Projekt-ID, Standort, Key-Ring, Crypto-Key, Cert-DER, PSR-Abhängigkeiten, optionale Chain, Config, LoggerErstellt GcpKmsConfig::fromEnvironment(), wenn $config null istselfDer Bezug des Bearer-Tokens wird an den Aufrufer delegiert
GcpKmsSigner::withAlgorithm()GcpKmsSigningAlgorithm $algorithmNur Vorschau zur Konfigurationszeit; der Wire-Name pro Aufruf gewinnt zur SignierzeitselfDie Schlüsselgröße ist durch die bereitgestellte CryptoKeyVersion festgelegt
AwsKmsSigningStrategyKonstruktor: AwsKmsSigner $signerSynchron; isAsync() gibt false zurückLeitet die Ausnahmen des umschlossenen Signierers weiterAdapter für RemoteSigningSession::complete()
AzureKeyVaultSigningStrategyKonstruktor: AzureKeyVaultSigner $signerSynchron; isAsync() gibt false zurückLeitet die Ausnahmen des umschlossenen Signierers weiterAdapter für RemoteSigningSession::complete()
KmsSigningAlgorithmEnum, 9 Fälle (RSA PKCS#1, RSA-PSS, ECDSA; SHA-256/384/512)AWS KMS-SigningAlgorithm-Wire-WerteInvalidArgumentException aus fromOpenSslName()resolveForWireName() bewahrt den konfigurierten PSS-Digest
AzureSigningAlgorithmEnum, 9 Fälle (RS256ES512)Azure Key Vault-Werte im JWA-StilInvalidArgumentException aus fromOpenSslName()isEcdsa() markiert Werte, deren Ausgabe eine DER-Konvertierung benötigt
GcpKmsSigningAlgorithmEnum, 10 Fälle (EC P-256/P-384, RSA PKCS#1, RSA-PSS)GCP CryptoKeyVersion-AlgorithmuswerteUnsupportedAlgorithmException aus fromOpenSslName()Die Wire-Name-Auflösung wählt die kleinste passende Schlüsselgröß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'): 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 erweitert den Core-Vertrag HsmSignerInterface. Es fügt providerId(), das schlüsselversionsbewusste signWithVersion() sowie die Fähigkeitsprüfungen supportsAlgorithm() und supportedAlgorithms() hinzu. Das geerbte Zwei-Argument-sign() delegiert bei allen drei Signierern mit einer null-Schlüsselversion an signWithVersion(). getCertificateDer(), getCertificateChainDer() und getPublicKeyAlgorithm() werden aus dem im Konstruktor bereitgestellten Material implementiert. Fähigkeitsprüfungen führen keine I/O aus. Jeder Signierer stellt zudem die Accessoren getSigningAlgorithm() und getConfig() zur Inspektion bereit.

Jeder Signierer hasht $data lokal mit dem Digest des aufgelösten Algorithmus und überträgt nur diesen Digest. AWS erhält einen Base64-Digest mit MessageType: DIGEST. Azure erhält einen Base64url-Digest im Body der Sign-Anfrage. GCP erhält einen Base64-Digest im algorithmusspezifischen Digest-Feld. Die Dokumentbytes erscheinen niemals in einer Anbieteranfrage. Der gesamte Transport verwendet einen Standard-PSR-18-HTTP-Client über den HTTPS-Endpunkt des Anbieters; kein Cloud-Anbieter-SDK ist beteiligt.

signWithVersion() validiert das Schlüsselversions-Argument fail-closed, bevor eine Anfrage erstellt wird. Ein Wert, der die Anbieter-Grammatik nicht erfüllt, löst KeyManagementException aus und verhindert die Injektion von URL-Segmenten oder KeyId.

Anbieternull-SchlüsselversionLeerer StringOverride-Grammatik
AwsKmsSignerVerwendet AwsKmsConfig::$keyId; ein Alias oder ARN wird anbieterseitig zum aktuellen Schlüssel aufgelöstAbgelehntUUID (mit oder ohne Bindestriche), alias/<name> oder ein KMS-Key-/Alias-ARN
AzureKeyVaultSignerVerwendet die konfigurierte Schlüsselversion; ein leerer Config-Wert wählt serverseitig die neueste aktivierte VersionAbgelehnt32-stelliger hexadezimaler Bezeichner
GcpKmsSignerVerwendet die in GcpKmsConfig fixierte Version; ist keine fixiert, löst KeyManagementException ausAbgelehntDezimale CryptoKeyVersion-ID, nur Ziffern

GCP besitzt kein serverseitiges Primitiv für eine „aktive Version”. Der Asymmetric-Sign-Endpunkt operiert ausschließlich auf einer bestimmten cryptoKeyVersions/{n}-Ressource, daher muss eine Version stets auflösbar sein.

Die Strategieebene reicht einen OpenSSL-artigen Wire-Namen weiter. AWS und Azure akzeptieren sieben Wire-Namen (PKCS#1 und ECDSA bei SHA-256/384/512 sowie RSASSA-PSS). GCP akzeptiert fünf (sha256WithRSAEncryption, sha512WithRSAEncryption, RSASSA-PSS, ecdsa-with-SHA256, ecdsa-with-SHA384). Der Wire-Name RSASSA-PSS kodiert keinen Digest und ist daher digest-mehrdeutig. AwsKmsSigner löst ihn über KmsSigningAlgorithm::resolveForWireName() auf, das den Digest der konfigurierten PSS-Variante bewahrt. AzureKeyVaultSigner vertraut für den mehrdeutigen Namen auf die konfigurierte PSS-Variante. Es löst UnsupportedAlgorithmException aus, wenn ein aufgelöster PSS-Digest von dem konfigurierten abweichen würde. GcpKmsSigner löst das Enum bei jedem Aufruf erneut aus dem Wire-Namen auf; withAlgorithm() ist bei GCP eine Vorschau zur Konfigurationszeit und ändert das Verhalten zur Signierzeit nicht. Ein nicht unterstützter Wire-Name löst UnsupportedAlgorithmException vor jedem Netzwerkaufruf aus. Bei AwsKmsSigner und GcpKmsSigner aktualisiert ein Sign-Aufruf den später von getSigningAlgorithm() gemeldeten Wert auf den pro Aufruf aufgelösten Algorithmus. Bei AzureKeyVaultSigner ist die Auflösung aufruflokal und der konfigurierte Wert bleibt maßgeblich.

AWS und GCP geben Signaturen in der Form zurück, die CMS konsumiert: RSA-Signatur-Oktette gelangen unverändert in SignerInfo.signature, und ECDSA kommt DER-kodiert an. Azure gibt ECDSA in roher IEEE-P1363-Form (r||s) zurück, die der Signierer vor der Rückgabe in ein DER-ECDSA-Sig-Value konvertiert.

Ein SigningStrategy-Adapter signiert die von der Session bereitgestellten DER-kodierten signierten Attribute. Sind signierte Attribute vorhanden, ist die CMS-Signatureingabe der Digest der vollständigen DER-Kodierung des SignedAttrs-Werts — RFC 5652 §5.4. Die Methoden getSignatureAlgorithmOid() und getDigestAlgorithm() des Adapters speisen die SignerInfo-Felder signatureAlgorithm und digestAlgorithm — RFC 5652 §5.3. Die zurückgegebenen Bytes werden zum SignerInfo-Signatur-OCTET-STRING — RFC 5652 §5.5. Der CMS-Aufbau, die ByteRange-Behandlung und der Session-Lebenszyklus gehören zu RemoteSigningSession; Mehrparteien-Abläufe gehören zu SequentialSigner. Ein PAdES-B-T-Signaturzeitstempel, dessen messageImprint den SignerInfo-Signaturwert hasht — RFC 3161 Appendix A —, wird von PadesBtTimestamper angewendet, nicht von diesen Signierern. Alle drei sind in der vertieften Pro-Sicherheitsreferenz dokumentiert.

  • Eine Schlüsselversion als leerer String wird bei allen drei Anbietern abgelehnt. Übergeben Sie null, um den konfigurierten Standard zu übernehmen.
  • Eine fehlerhafte Schlüsselversion wird abgelehnt, bevor eine Anfrage erstellt wird, wobei der beanstandete Wert in der Ausnahme benannt wird.
  • AwsKmsSigner mit einem leeren AwsKmsConfig::$keyId und einer null-Schlüsselversion löst KeyManagementException aus.
  • Anbieterantworten, die auf einen Schlüsselverwaltungsfehler hindeuten, werden auf KeyManagementException abgebildet: AWS NotFoundException, DisabledException, KeyUnavailableException, InvalidKeyUsageException oder HTTP 404; Azure HTTP 404, KeyNotFound, KeyDisabled oder KeyNotActive; GCP HTTP 404 oder 409, NOT_FOUND, FAILED_PRECONDITION oder ein HTTP 400, dessen Meldung eine Version benennt.
  • Andere Anbieterantworten ungleich 200 lösen SignatureFailedException bei AWS und GCP sowie AzureKeyVaultException bei Azure aus.
  • Ein PSR-18-Transportfehler während der Signierung wird auf SignatureFailedException abgebildet, wobei die Client-Ausnahme als vorheriges Throwable erhalten bleibt.
  • AzureKeyVaultSigner ohne Access-Token und ohne Service-Principal-Anmeldedaten löst AzureKeyVaultException vor jedem Vault-Aufruf aus. Ein fehlgeschlagener Bezug eines Azure-AD-Tokens löst ebenfalls AzureKeyVaultException aus.
  • AzureKeyVaultSigner validiert den Vault-Namen, den Schlüsselnamen, die Schlüsselversion und die Tenant-ID an der Anfrage-Engstelle gegen die von Azure veröffentlichten Grammatiken. Ein Wert mit URL-strukturellen Zeichen scheitert fail-closed mit AzureKeyVaultException.
  • GcpKmsSigner ohne OAuth2-Bearer-Token löst SignatureFailedException aus; der Bezug des Tokens liegt in der Verantwortung des Aufrufers.
  • Eine Anbieterantwort, die kein gültiges JSON ist oder der das Signaturfeld fehlt, löst SignatureFailedException aus (Azure: ein fehlendes value-Feld löst AzureKeyVaultException aus).
  • Ein Anbieter-Signaturfeld, das die Base64-Dekodierung nicht besteht, löst SignatureFailedException bei AWS und GCP sowie AzureKeyVaultException bei Azure aus.
  • In 3.1.0 wird kein SigningStrategy-Adapter für GcpKmsSigner ausgeliefert. Der GCP-Signierer wird direkt über den KmsSignerInterface-Vertrag konsumiert.

AwsKmsConfig::withFipsEndpoint() leitet Anfragen an den kms-fips-Endpunkt der Region. Der FIPS-Validierungsstatus dieses Endpunkts ist eine Eigenschaft von AWS, nicht von NextPDF. AzureKeyVaultConfig und GcpKmsConfig stellen in 3.1.0 keinen dedizierten FIPS-Endpunkt-Helfer bereit. Die Digest-Berechnung läuft prozessintern mit der PHP-Funktion hash() und ist selbst kein validiertes Modul. NextPDF Pro kann gegen eine FIPS-validierte KMS- oder HSM-Grenze arbeiten, aber NextPDF ist kein FIPS-validiertes kryptografisches Modul und erhebt keinen Anspruch auf eine FIPS-Zertifizierung.

AussageStandardKlausel
Die Strategie signiert die DER-kodierten signierten Attribute; der CMS-Signatureingabe-Digest deckt die vollständige DER-Kodierung von SignedAttrs ab.RFC 5652§5.4
SignedAttributes sind DER-kodiert und tragen mindestens content-type und message-digest; signatureAlgorithm identifiziert den Algorithmus des Signierers.RFC 5652§5.3
Die zurückgegebenen Signaturbytes werden als OCTET STRING kodiert und im SignerInfo-Signaturfeld getragen.RFC 5652§5.5
Der messageImprint eines Signaturzeitstempels hasht den SignerInfo-Signaturwert (angrenzende B-T-Fläche, nicht diese Signierer).RFC 3161Appendix A

Alle Klauseln sind paraphrasiert; NextPDF gibt keinen normativen Text wieder. Dies sind Fähigkeitsaussagen, keine Zertifizierungen. NextPDF besitzt keine Zertifizierung und gewährt keine. Ob eine erzeugte Signatur verifiziert, ist die Entscheidung des Verifizierers gegen dessen eigene Trust-Anchor und Richtlinie; die Signierer geben Signaturbytes zurück und sichern kein vertrauenswürdiges Ergebnis zu. Schlüsselverwahrung, Schlüsselschutz und anbieterseitige Algorithmusvalidierung sind Eigenschaften des konfigurierten KMS, nicht von NextPDF.

  • Verfügbarkeit innerhalb des Pro-Pakets: AwsKmsSigner seit 1.9.0, AzureKeyVaultSigner seit 2.0.0, GcpKmsSigner und KmsSignerInterface seit 2.1.0. Alle sind in nextpdf/pro 3.1.0 aktuell.
  • Die Signierer hängen nur von PSR-18, PSR-17 und PSR-3 ab. Kein AWS-, Azure- oder Google-SDK ist erforderlich oder gebündelt.
  • Prüfen Sie supportsAlgorithm() vor dem Signieren, damit ein inkompatibler Anbieter zur Auswahlzeit abgelehnt wird, nicht mitten in der Session.
  • Anmeldedatenfelder werden über den Konstruktor injiziert und als sensible Parameter markiert. Log-Nachrichten tragen nur strukturelle Felder; keine Anmeldedaten, kein Token und kein Dokumentinhalt werden in Logs geschrieben.
  • Fixieren Sie Schlüsselversionen in regulierten Bereitstellungen explizit. Die Standards Alias-Auflösung (AWS) und neueste-aktivierte (Azure) sind bequem, aber über Rotationen hinweg nicht deterministisch.
  • Drittanbieter-Treiber implementieren KmsSignerInterface und müssen ihr providerId() mit einem Namensraum versehen, um Kollisionen mit den reservierten eingebauten Bezeichnern zu vermeiden.

Diese Seite dokumentiert ausschließlich extern beobachtbares Verhalten und die unterstützte öffentliche API-Oberfläche. Interne Namensraumpfade, Hilfsklassen, Mechanismustabellen, Runbook-Dateinamen und Ticket-Präfixe liegen außerhalb des Umfangs.