Lewati ke konten
getnextpdf.com

Pro edisi

Penandatanganan Cloud KMS — Referensi Mendalam

Halaman ini adalah referensi tingkat-kontrak untuk permukaan penandatanganan cloud-KMS NextPDF Pro. Permukaan ini terdiri dari satu Service Provider Interface, NextPDF\Pro\Security\Signing\Kms\KmsSignerInterface, dan tiga signer provider: AwsKmsSigner, AzureKeyVaultSigner, dan GcpKmsSigner. Dua adapter, AwsKmsSigningStrategy dan AzureKeyVaultSigningStrategy, menjembatani sebuah signer ke kontrak SigningStrategy Pro. Setiap signer hanya mengirim message digest ke provider-nya melalui PSR-18 HTTP. Kunci privat dan dokumen tidak pernah melewati batas. Halaman ini menyatakan API publik, kontrak perilaku yang dapat diamati, dan mode kegagalan bertipe. Orkestrasi sesi (RemoteSigningSession, SequentialSigner) dan timestamping (PadesBtTimestamper) berada di halamannya sendiri.

Kapabilitas ini dikirim dalam NextPDF Pro (nextpdf/pro) dan diaktifkan dengan envelope lisensi tingkat-Pro. Deployment tanpa entitlement tersebut tidak memuat kelas-kelas kapabilitas ini. Bandingkan edisi dan dapatkan lisensi.

SimbolParameterPerilaku defaultMengembalikanMelempar atau gagal denganCatatan
KmsSignerInterfaceMemperluas kontrak Core HsmSignerInterfaceSPI untuk driver KMS dan HSM; id bawaan yang direservasi: aws-kms, azure-keyvault, gcp-kms, pkcs11, openssl-cli
KmsSignerInterface::providerId()noneKunci lookup registry yang stabilnon-empty-stringDriver pihak-ketiga harus memberi namespace pada identifiernya
KmsSignerInterface::signWithVersion()$data, $algorithm = 'sha256WithRSAEncryption', $keyVersion = nullVersi kunci null jatuh kembali ke default providerOktet tanda tangan string: RSA sebagaimana dikembalikan provider (ditempatkan langsung di SignerInfo.signature), ECDSA sebagai DER ECDSA-Sig-Value sesuai aturan CMSKeyManagementException, UnsupportedAlgorithmException, SignatureFailedExceptionSemantik null per-provider berbeda; lihat kontrak perilaku
KmsSignerInterface::supportsAlgorithm()string $algorithmProbe kapabilitas; tidak melakukan I/OboolDipanggil sebelum pemilihan provider
KmsSignerInterface::supportedAlgorithms()noneMendaftar nama gaya-OpenSSL yang diterima providerlist<non-empty-string>
AwsKmsSignerkonstruktor: AwsKmsConfig, cert DER, chain DER, klien PSR-18, factory PSR-17, logger PSR-3Algoritma default ke KmsSigningAlgorithm::RsaPkcs1Sha256lihat methodfinal; PROVIDER_ID = 'aws-kms'
AwsKmsSigner::create()key id, cert DER, dependensi PSR, chain opsional, config, loggerMembangun AwsKmsConfig::fromEnvironment($keyId) saat $config adalah nullselfMembaca variabel lingkungan AWS_* standar
AwsKmsSigner::withAlgorithm()KmsSigningAlgorithm $algorithmMengembalikan clone yang dimodifikasiselfHarus cocok dengan tipe kunci yang disediakan di AWS KMS
AwsKmsSigner::sign()$data, $algorithm = 'sha256WithRSAEncryption'Mendelegasikan ke signWithVersion($data, $algorithm, null)stringseperti signWithVersion()Jalur kontrak Core dua-argumen legacy
AzureKeyVaultSignerkonstruktor: AzureKeyVaultConfig, cert DER, chain DER, klien PSR-18, factory PSR-17, logger PSR-3Algoritma default ke AzureSigningAlgorithm::Rs256; sebuah access token config menyemai bearer tokenlihat methodfinal; PROVIDER_ID = 'azure-keyvault'
AzureKeyVaultSigner::create()nama vault, nama key, cert DER, dependensi PSR, chain opsional, config, loggerMembangun AzureKeyVaultConfig::fromEnvironment() saat $config adalah nullselfMendukung token yang telah diperoleh sebelumnya atau kredensial service-principal
AzureKeyVaultSigner::withAlgorithm()AzureSigningAlgorithm $algorithmMengembalikan clone yang dimodifikasiselfKunci RSA menggunakan nilai RS/PS; kunci EC menggunakan nilai ES
GcpKmsSignerkonstruktor: GcpKmsConfig, cert DER, chain DER, klien PSR-18, factory PSR-17, logger PSR-3Algoritma default ke GcpKmsSigningAlgorithm::RsaSignPkcs1_2048Sha256lihat methodfinal; PROVIDER_ID = 'gcp-kms', API_VERSION = 'v1'
GcpKmsSigner::create()project id, location, key ring, crypto key, cert DER, dependensi PSR, chain opsional, config, loggerMembangun GcpKmsConfig::fromEnvironment() saat $config adalah nullselfPerolehan bearer-token didelegasikan ke pemanggil
GcpKmsSigner::withAlgorithm()GcpKmsSigningAlgorithm $algorithmHanya preview saat-config; nama wire per-panggilan menang saat signselfUkuran kunci ditetapkan oleh CryptoKeyVersion yang disediakan
AwsKmsSigningStrategykonstruktor: AwsKmsSigner $signerSinkron; isAsync() mengembalikan falseMeneruskan eksepsi signer yang dibungkusAdapter untuk RemoteSigningSession::complete()
AzureKeyVaultSigningStrategykonstruktor: AzureKeyVaultSigner $signerSinkron; isAsync() mengembalikan falseMeneruskan eksepsi signer yang dibungkusAdapter untuk RemoteSigningSession::complete()
KmsSigningAlgorithmenum, 9 case (RSA PKCS#1, RSA-PSS, ECDSA; SHA-256/384/512)Nilai wire SigningAlgorithm AWS KMSInvalidArgumentException dari fromOpenSslName()resolveForWireName() mempertahankan digest PSS yang dikonfigurasi
AzureSigningAlgorithmenum, 9 case (RS256ES512)Nilai gaya-JWA Azure Key VaultInvalidArgumentException dari fromOpenSslName()isEcdsa() menandai nilai yang keluarannya perlu konversi DER
GcpKmsSigningAlgorithmenum, 10 case (EC P-256/P-384, RSA PKCS#1, RSA-PSS)Nilai algoritma CryptoKeyVersion GCPUnsupportedAlgorithmException dari fromOpenSslName()Resolusi nama-wire memilih ukuran kunci pencocokan terkecil
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 memperluas kontrak Core HsmSignerInterface. Ia menambahkan providerId(), signWithVersion() yang sadar-versi-kunci, serta probe kapabilitas supportsAlgorithm() dan supportedAlgorithms(). sign() dua-argumen yang diwarisi mendelegasikan ke signWithVersion() dengan versi kunci null pada ketiga signer. getCertificateDer(), getCertificateChainDer(), dan getPublicKeyAlgorithm() diimplementasikan dari material yang dipasok konstruktor. Probe kapabilitas tidak melakukan I/O. Setiap signer juga mengekspos accessor getSigningAlgorithm() dan getConfig() untuk inspeksi.

Setiap signer melakukan hash $data secara lokal dengan digest algoritma yang di-resolusi dan hanya mentransmisikan digest tersebut. AWS menerima digest base64 dengan MessageType: DIGEST. Azure menerima digest base64url di body request sign. GCP menerima digest base64 di field digest spesifik-algoritma. Byte dokumen tidak pernah muncul dalam request provider. Semua transport menggunakan klien HTTP PSR-18 standar melalui endpoint HTTPS provider; tidak ada SDK vendor cloud yang terlibat.

signWithVersion() memvalidasi argumen versi-kunci secara fail-closed sebelum request apa pun dibangun. Sebuah nilai yang gagal terhadap tata bahasa provider memunculkan KeyManagementException dan mencegah injeksi URL-segment atau KeyId.

ProviderVersi kunci nullString kosongTata bahasa override
AwsKmsSignerMenggunakan AwsKmsConfig::$keyId; alias atau ARN di-resolusi ke kunci saat ini di sisi providerDitolakUUID (dengan atau tanpa tanda hubung), alias/<name>, atau ARN key/alias KMS
AzureKeyVaultSignerMenggunakan versi kunci yang dikonfigurasi; nilai config kosong memilih versi enabled terbaru di sisi-serverDitolakIdentifier heksadesimal 32-karakter
GcpKmsSignerMenggunakan versi yang di-pin di GcpKmsConfig; tanpa pin, memunculkan KeyManagementExceptionDitolakId CryptoKeyVersion desimal, hanya digit

GCP tidak memiliki primitif “versi aktif” di sisi-server. Endpoint asymmetric-sign hanya beroperasi pada resource cryptoKeyVersions/{n} yang spesifik, sehingga sebuah versi harus selalu dapat di-resolusi.

Lapisan strategy meneruskan nama wire gaya-OpenSSL. AWS dan Azure menerima tujuh nama wire (PKCS#1 dan ECDSA pada SHA-256/384/512, plus RSASSA-PSS). GCP menerima lima (sha256WithRSAEncryption, sha512WithRSAEncryption, RSASSA-PSS, ecdsa-with-SHA256, ecdsa-with-SHA384). Nama wire RSASSA-PSS tidak mengencode sebuah digest, sehingga bersifat ambigu-digest. AwsKmsSigner me-resolusinya melalui KmsSigningAlgorithm::resolveForWireName(), yang mempertahankan digest dari varian PSS yang dikonfigurasi. AzureKeyVaultSigner mempercayai varian PSS yang dikonfigurasi untuk nama yang ambigu. Ia memunculkan UnsupportedAlgorithmException jika digest PSS yang di-resolusi menyimpang dari yang dikonfigurasi. GcpKmsSigner me-resolusi ulang enum dari nama wire pada setiap panggilan; withAlgorithm() pada GCP adalah preview saat-config dan tidak mengubah perilaku saat-sign. Nama wire yang tidak didukung memunculkan UnsupportedAlgorithmException sebelum panggilan jaringan apa pun. Pada AwsKmsSigner dan GcpKmsSigner, sebuah panggilan sign memperbarui nilai yang kemudian dilaporkan oleh getSigningAlgorithm() menjadi algoritma per-panggilan yang di-resolusi. Pada AzureKeyVaultSigner, resolusi bersifat lokal-panggilan dan nilai yang dikonfigurasi tetap otoritatif.

AWS dan GCP mengembalikan tanda tangan dalam bentuk yang dikonsumsi CMS: oktet tanda tangan RSA masuk ke SignerInfo.signature tanpa perubahan, dan ECDSA tiba dalam bentuk DER-encoded. Azure mengembalikan ECDSA dalam bentuk IEEE P1363 mentah (r||s), yang dikonversi signer menjadi DER ECDSA-Sig-Value sebelum mengembalikan.

Sebuah adapter SigningStrategy menandatangani signed attributes DER-encoded yang dipasok oleh sesi. Dengan signed attributes hadir, input tanda tangan CMS adalah digest dari pengkodean DER lengkap nilai SignedAttrs — RFC 5652 §5.4. getSignatureAlgorithmOid() dan getDigestAlgorithm() adapter memberi makan field SignerInfo signatureAlgorithm dan digestAlgorithm — RFC 5652 §5.3. Byte yang dikembalikan menjadi OCTET STRING tanda tangan SignerInfo — RFC 5652 §5.5. Perakitan CMS, penanganan ByteRange, dan siklus hidup sesi milik RemoteSigningSession; alur multi-pihak milik SequentialSigner. Sebuah signature-time-stamp PAdES B-T, yang messageImprint-nya melakukan hash pada nilai tanda tangan SignerInfo — RFC 3161 Appendix A — diterapkan oleh PadesBtTimestamper, bukan oleh signer-signer ini. Ketiganya didokumentasikan pada referensi mendalam keamanan Pro.

  • Versi kunci berupa string-kosong ditolak pada ketiga provider. Berikan null untuk mewarisi default yang dikonfigurasi.
  • Versi kunci yang cacat ditolak sebelum request apa pun dibangun, dengan nilai yang bermasalah disebutkan dalam eksepsi.
  • AwsKmsSigner dengan AwsKmsConfig::$keyId kosong dan versi kunci null memunculkan KeyManagementException.
  • Respons provider yang mengindikasikan kegagalan key-management dipetakan ke KeyManagementException: AWS NotFoundException, DisabledException, KeyUnavailableException, InvalidKeyUsageException, atau HTTP 404; Azure HTTP 404, KeyNotFound, KeyDisabled, atau KeyNotActive; GCP HTTP 404 atau 409, NOT_FOUND, FAILED_PRECONDITION, atau HTTP 400 yang pesannya menyebut sebuah versi.
  • Respons provider non-200 lainnya memunculkan SignatureFailedException pada AWS dan GCP, dan AzureKeyVaultException pada Azure.
  • Kegagalan transport PSR-18 selama penandatanganan dipetakan ke SignatureFailedException dengan eksepsi klien dipertahankan sebagai throwable sebelumnya.
  • AzureKeyVaultSigner tanpa access token dan tanpa kredensial service-principal memunculkan AzureKeyVaultException sebelum panggilan vault apa pun. Perolehan token Azure AD yang gagal juga memunculkan AzureKeyVaultException.
  • AzureKeyVaultSigner memvalidasi nama vault, nama key, versi key, dan tenant id terhadap tata bahasa yang dipublikasikan Azure di chokepoint request. Sebuah nilai yang membawa karakter URL-struktural gagal secara tertutup dengan AzureKeyVaultException.
  • GcpKmsSigner tanpa bearer token OAuth2 memunculkan SignatureFailedException; perolehan token adalah tanggung jawab pemanggil.
  • Respons provider yang bukan JSON valid, atau yang tidak memiliki field tanda tangan, memunculkan SignatureFailedException (Azure: field value yang hilang memunculkan AzureKeyVaultException).
  • Field tanda tangan provider yang gagal decoding base64 memunculkan SignatureFailedException pada AWS dan GCP, dan AzureKeyVaultException pada Azure.
  • Tidak ada adapter SigningStrategy untuk GcpKmsSigner yang dikirim pada 3.1.0. Signer GCP dikonsumsi melalui kontrak KmsSignerInterface secara langsung.

AwsKmsConfig::withFipsEndpoint() merutekan request ke endpoint kms-fips region. Status validasi FIPS dari endpoint tersebut adalah properti AWS, bukan NextPDF. AzureKeyVaultConfig dan GcpKmsConfig tidak mengekspos helper endpoint FIPS khusus pada 3.1.0. Komputasi digest berjalan in-process dengan fungsi PHP hash() dan bukan merupakan modul tervalidasi. NextPDF Pro dapat beroperasi terhadap batas KMS atau HSM yang tervalidasi-FIPS, tetapi NextPDF bukan modul kriptografi yang tervalidasi-FIPS dan tidak membuat klaim sertifikasi FIPS.

KlaimStandarKlausa
Strategy menandatangani signed attributes DER-encoded; digest input tanda tangan CMS mencakup pengkodean DER lengkap dari SignedAttrs.RFC 5652§5.4
SignedAttributes bersifat DER-encoded dan membawa content-type dan message-digest minimal; signatureAlgorithm mengidentifikasi algoritma signer.RFC 5652§5.3
Byte tanda tangan yang dikembalikan dienkode sebagai OCTET STRING dan dibawa di field tanda tangan SignerInfo.RFC 5652§5.5
messageImprint sebuah signature time-stamp melakukan hash pada nilai tanda tangan SignerInfo (permukaan B-T yang berdekatan, bukan signer-signer ini).RFC 3161Appendix A

Semua klausa diparafrasakan; NextPDF tidak mereproduksi teks normatif. Ini adalah pernyataan kapabilitas, bukan sertifikasi. NextPDF tidak memegang sertifikasi dan tidak memberikan sertifikasi apa pun. Apakah tanda tangan yang diproduksi terverifikasi adalah keputusan verifier terhadap trust anchor dan kebijakannya sendiri; signer mengembalikan byte tanda tangan dan tidak menegaskan hasil yang tepercaya apa pun. Kustodi kunci, proteksi kunci, dan validasi algoritma di sisi-provider adalah properti KMS yang dikonfigurasi, bukan NextPDF.

  • Ketersediaan di dalam paket Pro: AwsKmsSigner sejak 1.9.0, AzureKeyVaultSigner sejak 2.0.0, GcpKmsSigner dan KmsSignerInterface sejak 2.1.0. Semuanya terkini di nextpdf/pro 3.1.0.
  • Signer hanya bergantung pada PSR-18, PSR-17, dan PSR-3. Tidak ada SDK AWS, Azure, atau Google yang diperlukan atau dibundel.
  • Probe supportsAlgorithm() sebelum menandatangani agar provider yang tidak kompatibel ditolak saat pemilihan, bukan di tengah-sesi.
  • Field kredensial diinjeksi-konstruktor dan ditandai sebagai parameter sensitif. Pesan log hanya membawa field struktural; tidak ada kredensial, token, atau konten dokumen yang ditulis ke log.
  • Pin versi kunci secara eksplisit di deployment yang teregulasi. Default alias-resolution (AWS) dan latest-enabled (Azure) memang nyaman tetapi tidak deterministik lintas rotasi.
  • Driver pihak-ketiga mengimplementasikan KmsSignerInterface dan harus memberi namespace pada providerId()-nya untuk menghindari tabrakan dengan identifier bawaan yang direservasi.

Halaman ini hanya mendokumentasikan perilaku yang dapat diamati secara eksternal dan permukaan API publik yang didukung. Jalur namespace internal, kelas helper, tabel mekanisme, nama file runbook, dan prefix tiket berada di luar cakupan.