Przejdź do głównej zawartości
getnextpdf.com

Pro edycja

Podpisywanie w chmurowym KMS — pełna dokumentacja referencyjna

Ta strona to referencja na poziomie kontraktu dla powierzchni podpisywania w chmurowym KMS w NextPDF Pro. Powierzchnia składa się z jednego Service Provider Interface, NextPDF\Pro\Security\Signing\Kms\KmsSignerInterface, oraz trzech podpisujących dostawców: AwsKmsSigner, AzureKeyVaultSigner i GcpKmsSigner. Dwa adaptery, AwsKmsSigningStrategy i AzureKeyVaultSigningStrategy, łączą podpisującego z kontraktem SigningStrategy w edycji Pro. Każdy podpisujący wysyła do swojego dostawcy jedynie skrót wiadomości przez HTTP zgodny z PSR-18. Klucz prywatny i dokument nigdy nie przekraczają granicy. Ta strona przedstawia publiczne API, kontrakt obserwowalnego zachowania oraz typowane tryby awarii. Orkiestracja sesji (RemoteSigningSession, SequentialSigner) i znakowanie czasem (PadesBtTimestamper) mają własne strony.

Ta funkcja dostarczana jest w NextPDF Pro (nextpdf/pro) i aktywuje się kopertą licencyjną poziomu Pro. Wdrożenie bez tego uprawnienia nie ładuje klas tej funkcji. Porównaj edycje i uzyskaj licencję.

SymbolParametryZachowanie domyślneZwracaRzuca lub kończy się błędemUwagi
KmsSignerInterfaceRozszerza kontrakt Core HsmSignerInterfaceSPI dla sterowników KMS i HSM; zarezerwowane wbudowane identyfikatory: aws-kms, azure-keyvault, gcp-kms, pkcs11, openssl-cli
KmsSignerInterface::providerId()brakStabilny klucz wyszukiwania w rejestrzenon-empty-stringSterowniki firm trzecich muszą nadać swojemu identyfikatorowi przestrzeń nazw
KmsSignerInterface::signWithVersion()$data, $algorithm = 'sha256WithRSAEncryption', $keyVersion = nullWersja klucza null cofa się do domyślnej dostawcyoktety podpisu string: RSA tak, jak zwrócone przez dostawcę (umieszczane bezpośrednio w SignerInfo.signature), ECDSA jako DER ECDSA-Sig-Value zgodnie z regułami CMSKeyManagementException, UnsupportedAlgorithmException, SignatureFailedExceptionSemantyka null różni się per dostawca; zobacz kontrakt zachowania
KmsSignerInterface::supportsAlgorithm()string $algorithmSonda możliwości; nie wykonuje I/OboolWywoływana przed wyborem dostawcy
KmsSignerInterface::supportedAlgorithms()brakWylicza nazwy w stylu OpenSSL akceptowane przez dostawcęlist<non-empty-string>
AwsKmsSignerkonstruktor: AwsKmsConfig, cert DER, chain DER, klient PSR-18, fabryki PSR-17, logger PSR-3Algorytm domyślnie KmsSigningAlgorithm::RsaPkcs1Sha256zobacz metodyfinal; PROVIDER_ID = 'aws-kms'
AwsKmsSigner::create()identyfikator klucza, cert DER, zależności PSR, opcjonalny łańcuch, konfiguracja, loggerBuduje AwsKmsConfig::fromEnvironment($keyId), gdy $config jest nullselfOdczytuje standardowe zmienne środowiskowe AWS_*
AwsKmsSigner::withAlgorithm()KmsSigningAlgorithm $algorithmZwraca zmodyfikowany klonselfMusi pasować do typu klucza zaprowizjonowanego w AWS KMS
AwsKmsSigner::sign()$data, $algorithm = 'sha256WithRSAEncryption'Deleguje do signWithVersion($data, $algorithm, null)stringjak signWithVersion()Ścieżka starszego dwuargumentowego kontraktu Core
AzureKeyVaultSignerkonstruktor: AzureKeyVaultConfig, cert DER, chain DER, klient PSR-18, fabryki PSR-17, logger PSR-3Algorytm domyślnie AzureSigningAlgorithm::Rs256; token dostępu z konfiguracji zasila token bearerzobacz metodyfinal; PROVIDER_ID = 'azure-keyvault'
AzureKeyVaultSigner::create()nazwa skarbca, nazwa klucza, cert DER, zależności PSR, opcjonalny łańcuch, konfiguracja, loggerBuduje AzureKeyVaultConfig::fromEnvironment(), gdy $config jest nullselfObsługuje wcześniej uzyskany token lub poświadczenia jednostki usługowej
AzureKeyVaultSigner::withAlgorithm()AzureSigningAlgorithm $algorithmZwraca zmodyfikowany klonselfKlucze RSA używają wartości RS/PS; klucze EC używają wartości ES
GcpKmsSignerkonstruktor: GcpKmsConfig, cert DER, chain DER, klient PSR-18, fabryki PSR-17, logger PSR-3Algorytm domyślnie GcpKmsSigningAlgorithm::RsaSignPkcs1_2048Sha256zobacz metodyfinal; PROVIDER_ID = 'gcp-kms', API_VERSION = 'v1'
GcpKmsSigner::create()identyfikator projektu, lokalizacja, key ring, crypto key, cert DER, zależności PSR, opcjonalny łańcuch, konfiguracja, loggerBuduje GcpKmsConfig::fromEnvironment(), gdy $config jest nullselfPozyskanie tokenu bearer jest delegowane do wywołującego
GcpKmsSigner::withAlgorithm()GcpKmsSigningAlgorithm $algorithmTylko podgląd w czasie konfiguracji; nazwa wire per wywołanie wygrywa w czasie podpisywaniaselfRozmiar klucza jest ustalony przez zaprowizjonowaną CryptoKeyVersion
AwsKmsSigningStrategykonstruktor: AwsKmsSigner $signerSynchroniczny; isAsync() zwraca falsePropaguje wyjątki opakowanego podpisującegoAdapter dla RemoteSigningSession::complete()
AzureKeyVaultSigningStrategykonstruktor: AzureKeyVaultSigner $signerSynchroniczny; isAsync() zwraca falsePropaguje wyjątki opakowanego podpisującegoAdapter dla RemoteSigningSession::complete()
KmsSigningAlgorithmenum, 9 przypadków (RSA PKCS#1, RSA-PSS, ECDSA; SHA-256/384/512)Wartości wire SigningAlgorithm AWS KMSInvalidArgumentException z fromOpenSslName()resolveForWireName() zachowuje skonfigurowany skrót PSS
AzureSigningAlgorithmenum, 9 przypadków (RS256ES512)Wartości w stylu JWA Azure Key VaultInvalidArgumentException z fromOpenSslName()isEcdsa() oznacza wartości, których wynik wymaga konwersji DER
GcpKmsSigningAlgorithmenum, 10 przypadków (EC P-256/P-384, RSA PKCS#1, RSA-PSS)Wartości algorytmu CryptoKeyVersion GCPUnsupportedAlgorithmException z fromOpenSslName()Rozwiązanie nazwy wire wybiera najmniejszy pasujący rozmiar klucza
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 rozszerza kontrakt Core HsmSignerInterface. Dodaje providerId(), świadome wersji klucza signWithVersion() oraz sondy możliwości supportsAlgorithm() i supportedAlgorithms(). Dziedziczone dwuargumentowe sign() deleguje do signWithVersion() z wersją klucza null we wszystkich trzech podpisujących. getCertificateDer(), getCertificateChainDer() i getPublicKeyAlgorithm() są implementowane z materiału dostarczonego przez konstruktor. Sondy możliwości nie wykonują I/O. Każdy podpisujący udostępnia także akcesory getSigningAlgorithm() i getConfig() do inspekcji.

Każdy podpisujący haszuje $data lokalnie skrótem rozwiązanego algorytmu i przesyła jedynie ten skrót. AWS otrzymuje skrót w base64 z MessageType: DIGEST. Azure otrzymuje skrót w base64url w treści żądania podpisu. GCP otrzymuje skrót w base64 w polu skrótu specyficznym dla algorytmu. Bajty dokumentu nigdy nie pojawiają się w żądaniu do dostawcy. Cały transport korzysta ze standardowego klienta HTTP PSR-18 nad punktem końcowym HTTPS dostawcy; nie jest zaangażowany żaden SDK dostawcy chmurowego.

signWithVersion() waliduje argument wersji klucza w trybie fail-closed przed zbudowaniem jakiegokolwiek żądania. Wartość, która nie spełnia gramatyki dostawcy, rzuca KeyManagementException i zapobiega wstrzyknięciu segmentu URL lub KeyId.

DostawcaWersja klucza nullPusty łańcuchGramatyka nadpisania
AwsKmsSignerUżywa AwsKmsConfig::$keyId; alias lub ARN rozwiązuje się do bieżącego klucza po stronie dostawcyOdrzucanyUUID (z myślnikami lub bez), alias/<name> lub ARN klucza/aliasu KMS
AzureKeyVaultSignerUżywa skonfigurowanej wersji klucza; pusta wartość konfiguracji wybiera najnowszą włączoną wersję po stronie serweraOdrzucany32-znakowy identyfikator szesnastkowy
GcpKmsSignerUżywa wersji przypiętej w GcpKmsConfig; gdy żadna nie jest przypięta, rzuca KeyManagementExceptionOdrzucanyDziesiętny identyfikator CryptoKeyVersion, wyłącznie cyfry

GCP nie ma po stronie serwera prymitywu „aktywnej wersji”. Punkt końcowy asymmetric-sign operuje wyłącznie na konkretnym zasobie cryptoKeyVersions/{n}, więc wersja musi być zawsze rozwiązywalna.

Warstwa strategii przekazuje nazwę wire w stylu OpenSSL. AWS i Azure akceptują siedem nazw wire (PKCS#1 i ECDSA przy SHA-256/384/512, plus RSASSA-PSS). GCP akceptuje pięć (sha256WithRSAEncryption, sha512WithRSAEncryption, RSASSA-PSS, ecdsa-with-SHA256, ecdsa-with-SHA384). Nazwa wire RSASSA-PSS nie koduje skrótu, więc jest niejednoznaczna co do skrótu. AwsKmsSigner rozwiązuje ją przez KmsSigningAlgorithm::resolveForWireName(), co zachowuje skrót skonfigurowanego wariantu PSS. AzureKeyVaultSigner ufa skonfigurowanemu wariantowi PSS dla niejednoznacznej nazwy. Rzuca UnsupportedAlgorithmException, jeśli rozwiązany skrót PSS odbiegałby od skonfigurowanego. GcpKmsSigner ponownie rozwiązuje enum z nazwy wire przy każdym wywołaniu; withAlgorithm() w GCP to podgląd w czasie konfiguracji i nie zmienia zachowania w czasie podpisywania. Nieobsługiwana nazwa wire rzuca UnsupportedAlgorithmException przed jakimkolwiek wywołaniem sieciowym. W AwsKmsSigner i GcpKmsSigner wywołanie podpisu aktualizuje wartość później raportowaną przez getSigningAlgorithm() do rozwiązanego algorytmu per wywołanie. W AzureKeyVaultSigner rozwiązanie jest lokalne dla wywołania, a skonfigurowana wartość pozostaje miarodajna.

AWS i GCP zwracają podpisy w postaci, którą konsumuje CMS: oktety podpisu RSA trafiają do SignerInfo.signature bez zmian, a ECDSA przychodzi zakodowane w DER. Azure zwraca ECDSA w surowej postaci IEEE P1363 (r||s), którą podpisujący konwertuje na DER ECDSA-Sig-Value przed zwróceniem.

Adapter SigningStrategy podpisuje zakodowane w DER podpisane atrybuty dostarczone przez sesję. Gdy podpisane atrybuty są obecne, wejściem podpisu CMS jest skrót kompletnego kodowania DER wartości SignedAttrs — RFC 5652 §5.4. Metody adaptera getSignatureAlgorithmOid() i getDigestAlgorithm() zasilają pola SignerInfo signatureAlgorithm i digestAlgorithm — RFC 5652 §5.3. Zwrócone bajty stają się OCTET STRING podpisu SignerInfo — RFC 5652 §5.5. Montaż CMS, obsługa ByteRange i cykl życia sesji należą do RemoteSigningSession; przepływy wielostronne należą do SequentialSigner. Znacznik czasu podpisu PAdES B-T, którego messageImprint haszuje wartość podpisu SignerInfo — RFC 3161 Appendix A — jest nakładany przez PadesBtTimestamper, a nie przez te podpisujące. Wszystkie trzy są udokumentowane w pełnej dokumentacji referencyjnej bezpieczeństwa Pro.

  • Pusta wartość wersji klucza jest odrzucana u wszystkich trzech dostawców. Przekaż null, aby odziedziczyć skonfigurowaną wartość domyślną.
  • Zniekształcona wersja klucza jest odrzucana przed zbudowaniem jakiegokolwiek żądania, z nazwaną w wyjątku wartością naruszającą.
  • AwsKmsSigner z pustym AwsKmsConfig::$keyId i wersją klucza null rzuca KeyManagementException.
  • Odpowiedzi dostawcy wskazujące na awarię zarządzania kluczem mapują się do KeyManagementException: AWS NotFoundException, DisabledException, KeyUnavailableException, InvalidKeyUsageException lub HTTP 404; Azure HTTP 404, KeyNotFound, KeyDisabled lub KeyNotActive; GCP HTTP 404 lub 409, NOT_FOUND, FAILED_PRECONDITION lub HTTP 400, którego komunikat nazywa wersję.
  • Inne odpowiedzi dostawcy inne niż 200 rzucają SignatureFailedException w AWS i GCP oraz AzureKeyVaultException w Azure.
  • Awaria transportu PSR-18 podczas podpisywania mapuje się do SignatureFailedException z wyjątkiem klienta zachowanym jako poprzedni obiekt rzucalny.
  • AzureKeyVaultSigner bez tokenu dostępu i bez poświadczeń jednostki usługowej rzuca AzureKeyVaultException przed jakimkolwiek wywołaniem skarbca. Nieudane pozyskanie tokenu Azure AD również rzuca AzureKeyVaultException.
  • AzureKeyVaultSigner waliduje nazwę skarbca, nazwę klucza, wersję klucza i identyfikator dzierżawy względem opublikowanych gramatyk Azure w punkcie kontroli żądania. Wartość zawierająca znaki strukturalne URL kończy się fail-closed z AzureKeyVaultException.
  • GcpKmsSigner bez tokenu bearer OAuth2 rzuca SignatureFailedException; pozyskanie tokenu jest odpowiedzialnością wywołującego.
  • Odpowiedź dostawcy, która nie jest poprawnym JSON-em lub której brakuje pola podpisu, rzuca SignatureFailedException (Azure: brakujące pole value rzuca AzureKeyVaultException).
  • Pole podpisu dostawcy, którego dekodowanie base64 się nie powiedzie, rzuca SignatureFailedException w AWS i GCP oraz AzureKeyVaultException w Azure.
  • W wersji 3.1.0 nie jest dostarczany żaden adapter SigningStrategy dla GcpKmsSigner. Podpisujący GCP jest konsumowany bezpośrednio przez kontrakt KmsSignerInterface.

AwsKmsConfig::withFipsEndpoint() kieruje żądania do punktu końcowego kms-fips regionu. Status walidacji FIPS tego punktu końcowego jest właściwością AWS, a nie NextPDF. AzureKeyVaultConfig i GcpKmsConfig nie udostępniają w wersji 3.1.0 dedykowanego pomocnika punktu końcowego FIPS. Obliczanie skrótu przebiega w procesie za pomocą funkcji PHP hash() i samo w sobie nie jest walidowanym modułem. NextPDF Pro może działać względem granicy KMS lub HSM walidowanej pod kątem FIPS, ale NextPDF nie jest walidowanym pod kątem FIPS modułem kryptograficznym i nie formułuje żadnego roszczenia o certyfikacji FIPS.

RoszczenieStandardKlauzula
Strategia podpisuje zakodowane w DER podpisane atrybuty; skrót wejściowy podpisu CMS pokrywa kompletne kodowanie DER SignedAttrs.RFC 5652§5.4
SignedAttributes są zakodowane w DER i niosą co najmniej content-type i message-digest; signatureAlgorithm identyfikuje algorytm podpisującego.RFC 5652§5.3
Zwrócone bajty podpisu są zakodowane jako OCTET STRING i niesione w polu podpisu SignerInfo.RFC 5652§5.5
messageImprint znacznika czasu podpisu haszuje wartość podpisu SignerInfo (powierzchnia sąsiadująca B-T, nie te podpisujące).RFC 3161Appendix A

Wszystkie klauzule są parafrazowane; NextPDF nie odtwarza tekstu normatywnego. Są to stwierdzenia o możliwościach, nie certyfikaty. NextPDF nie posiada żadnej certyfikacji ani jej nie udziela. To, czy wytworzony podpis się zweryfikuje, jest decyzją weryfikatora względem jego własnych kotwic zaufania i polityki; podpisujące zwracają bajty podpisu i nie zapewniają żadnego zaufanego wyniku. Nadzór nad kluczem, ochrona klucza i walidacja algorytmu po stronie dostawcy są właściwościami skonfigurowanego KMS, a nie NextPDF.

  • Dostępność w pakiecie Pro: AwsKmsSigner od 1.9.0, AzureKeyVaultSigner od 2.0.0, GcpKmsSigner i KmsSignerInterface od 2.1.0. Wszystkie są aktualne w nextpdf/pro 3.1.0.
  • Podpisujące zależą wyłącznie od PSR-18, PSR-17 i PSR-3. Nie jest wymagany ani dołączany żaden SDK AWS, Azure czy Google.
  • Sonduj supportsAlgorithm() przed podpisaniem, aby niekompatybilny dostawca został odrzucony w czasie wyboru, a nie w trakcie sesji.
  • Pola poświadczeń są wstrzykiwane przez konstruktor i oznaczone jako parametry wrażliwe. Komunikaty logów niosą wyłącznie pola strukturalne; do logów nie jest zapisywane żadne poświadczenie, token ani treść dokumentu.
  • Przypinaj wersje kluczy jawnie we wdrożeniach regulowanych. Domyślne rozwiązywanie aliasu (AWS) i najnowszej włączonej wersji (Azure) są wygodne, ale niedeterministyczne między rotacjami.
  • Sterowniki firm trzecich implementują KmsSignerInterface i muszą nadać swojemu providerId() przestrzeń nazw, aby uniknąć kolizji z zarezerwowanymi wbudowanymi identyfikatorami.

Ta strona dokumentuje wyłącznie zewnętrznie obserwowalne zachowanie i wspieraną powierzchnię publicznego API. Wewnętrzne ścieżki przestrzeni nazw, klasy pomocnicze, tabele mechanizmów, nazwy plików runbooków i prefiksy zgłoszeń są poza zakresem.