Pro edisi
Penandatanganan Cloud KMS — Referensi Mendalam
Sekilas pandang
Bagian berjudul “Sekilas pandang”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.
Ketersediaan & lisensi
Bagian berjudul “Ketersediaan & lisensi”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.
Permukaan API publik
Bagian berjudul “Permukaan API publik”| Simbol | Parameter | Perilaku default | Mengembalikan | Melempar atau gagal dengan | Catatan |
|---|---|---|---|---|---|
KmsSignerInterface | — | Memperluas kontrak Core HsmSignerInterface | — | — | SPI untuk driver KMS dan HSM; id bawaan yang direservasi: aws-kms, azure-keyvault, gcp-kms, pkcs11, openssl-cli |
KmsSignerInterface::providerId() | none | Kunci lookup registry yang stabil | non-empty-string | — | Driver pihak-ketiga harus memberi namespace pada identifiernya |
KmsSignerInterface::signWithVersion() | $data, $algorithm = 'sha256WithRSAEncryption', $keyVersion = null | Versi kunci null jatuh kembali ke default provider | Oktet tanda tangan string: RSA sebagaimana dikembalikan provider (ditempatkan langsung di SignerInfo.signature), ECDSA sebagai DER ECDSA-Sig-Value sesuai aturan CMS | KeyManagementException, UnsupportedAlgorithmException, SignatureFailedException | Semantik null per-provider berbeda; lihat kontrak perilaku |
KmsSignerInterface::supportsAlgorithm() | string $algorithm | Probe kapabilitas; tidak melakukan I/O | bool | — | Dipanggil sebelum pemilihan provider |
KmsSignerInterface::supportedAlgorithms() | none | Mendaftar nama gaya-OpenSSL yang diterima provider | list<non-empty-string> | — | — |
AwsKmsSigner | konstruktor: AwsKmsConfig, cert DER, chain DER, klien PSR-18, factory PSR-17, logger PSR-3 | Algoritma default ke KmsSigningAlgorithm::RsaPkcs1Sha256 | — | lihat method | final; PROVIDER_ID = 'aws-kms' |
AwsKmsSigner::create() | key id, cert DER, dependensi PSR, chain opsional, config, logger | Membangun AwsKmsConfig::fromEnvironment($keyId) saat $config adalah null | self | — | Membaca variabel lingkungan AWS_* standar |
AwsKmsSigner::withAlgorithm() | KmsSigningAlgorithm $algorithm | Mengembalikan clone yang dimodifikasi | self | — | Harus cocok dengan tipe kunci yang disediakan di AWS KMS |
AwsKmsSigner::sign() | $data, $algorithm = 'sha256WithRSAEncryption' | Mendelegasikan ke signWithVersion($data, $algorithm, null) | string | seperti signWithVersion() | Jalur kontrak Core dua-argumen legacy |
AzureKeyVaultSigner | konstruktor: AzureKeyVaultConfig, cert DER, chain DER, klien PSR-18, factory PSR-17, logger PSR-3 | Algoritma default ke AzureSigningAlgorithm::Rs256; sebuah access token config menyemai bearer token | — | lihat method | final; PROVIDER_ID = 'azure-keyvault' |
AzureKeyVaultSigner::create() | nama vault, nama key, cert DER, dependensi PSR, chain opsional, config, logger | Membangun AzureKeyVaultConfig::fromEnvironment() saat $config adalah null | self | — | Mendukung token yang telah diperoleh sebelumnya atau kredensial service-principal |
AzureKeyVaultSigner::withAlgorithm() | AzureSigningAlgorithm $algorithm | Mengembalikan clone yang dimodifikasi | self | — | Kunci RSA menggunakan nilai RS/PS; kunci EC menggunakan nilai ES |
GcpKmsSigner | konstruktor: GcpKmsConfig, cert DER, chain DER, klien PSR-18, factory PSR-17, logger PSR-3 | Algoritma default ke GcpKmsSigningAlgorithm::RsaSignPkcs1_2048Sha256 | — | lihat method | final; PROVIDER_ID = 'gcp-kms', API_VERSION = 'v1' |
GcpKmsSigner::create() | project id, location, key ring, crypto key, cert DER, dependensi PSR, chain opsional, config, logger | Membangun GcpKmsConfig::fromEnvironment() saat $config adalah null | self | — | Perolehan bearer-token didelegasikan ke pemanggil |
GcpKmsSigner::withAlgorithm() | GcpKmsSigningAlgorithm $algorithm | Hanya preview saat-config; nama wire per-panggilan menang saat sign | self | — | Ukuran kunci ditetapkan oleh CryptoKeyVersion yang disediakan |
AwsKmsSigningStrategy | konstruktor: AwsKmsSigner $signer | Sinkron; isAsync() mengembalikan false | — | Meneruskan eksepsi signer yang dibungkus | Adapter untuk RemoteSigningSession::complete() |
AzureKeyVaultSigningStrategy | konstruktor: AzureKeyVaultSigner $signer | Sinkron; isAsync() mengembalikan false | — | Meneruskan eksepsi signer yang dibungkus | Adapter untuk RemoteSigningSession::complete() |
KmsSigningAlgorithm | enum, 9 case (RSA PKCS#1, RSA-PSS, ECDSA; SHA-256/384/512) | — | Nilai wire SigningAlgorithm AWS KMS | InvalidArgumentException dari fromOpenSslName() | resolveForWireName() mempertahankan digest PSS yang dikonfigurasi |
AzureSigningAlgorithm | enum, 9 case (RS256…ES512) | — | Nilai gaya-JWA Azure Key Vault | InvalidArgumentException dari fromOpenSslName() | isEcdsa() menandai nilai yang keluarannya perlu konversi DER |
GcpKmsSigningAlgorithm | enum, 10 case (EC P-256/P-384, RSA PKCS#1, RSA-PSS) | — | Nilai algoritma CryptoKeyVersion GCP | UnsupportedAlgorithmException dari fromOpenSslName() | Resolusi nama-wire memilih ukuran kunci pencocokan terkecil |
Signature entry-point
Bagian berjudul “Signature entry-point”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): stringKontrak perilaku
Bagian berjudul “Kontrak perilaku”Resolusi kontrak
Bagian berjudul “Resolusi kontrak”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.
Transmisi digest-saja
Bagian berjudul “Transmisi digest-saja”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.
Resolusi versi kunci
Bagian berjudul “Resolusi versi kunci”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.
| Provider | Versi kunci null | String kosong | Tata bahasa override |
|---|---|---|---|
AwsKmsSigner | Menggunakan AwsKmsConfig::$keyId; alias atau ARN di-resolusi ke kunci saat ini di sisi provider | Ditolak | UUID (dengan atau tanpa tanda hubung), alias/<name>, atau ARN key/alias KMS |
AzureKeyVaultSigner | Menggunakan versi kunci yang dikonfigurasi; nilai config kosong memilih versi enabled terbaru di sisi-server | Ditolak | Identifier heksadesimal 32-karakter |
GcpKmsSigner | Menggunakan versi yang di-pin di GcpKmsConfig; tanpa pin, memunculkan KeyManagementException | Ditolak | Id 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.
Resolusi algoritma
Bagian berjudul “Resolusi algoritma”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.
Normalisasi tanda tangan
Bagian berjudul “Normalisasi tanda tangan”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.
Integrasi CMS dan kedekatan
Bagian berjudul “Integrasi CMS dan kedekatan”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.
Kasus tepi & mode kegagalan
Bagian berjudul “Kasus tepi & mode kegagalan”- Versi kunci berupa string-kosong ditolak pada ketiga provider. Berikan
nulluntuk mewarisi default yang dikonfigurasi. - Versi kunci yang cacat ditolak sebelum request apa pun dibangun, dengan nilai yang bermasalah disebutkan dalam eksepsi.
AwsKmsSignerdenganAwsKmsConfig::$keyIdkosong dan versi kuncinullmemunculkanKeyManagementException.- Respons provider yang mengindikasikan kegagalan key-management dipetakan ke
KeyManagementException: AWSNotFoundException,DisabledException,KeyUnavailableException,InvalidKeyUsageException, atau HTTP 404; Azure HTTP 404,KeyNotFound,KeyDisabled, atauKeyNotActive; GCP HTTP 404 atau 409,NOT_FOUND,FAILED_PRECONDITION, atau HTTP 400 yang pesannya menyebut sebuah versi. - Respons provider non-200 lainnya memunculkan
SignatureFailedExceptionpada AWS dan GCP, danAzureKeyVaultExceptionpada Azure. - Kegagalan transport PSR-18 selama penandatanganan dipetakan ke
SignatureFailedExceptiondengan eksepsi klien dipertahankan sebagai throwable sebelumnya. AzureKeyVaultSignertanpa access token dan tanpa kredensial service-principal memunculkanAzureKeyVaultExceptionsebelum panggilan vault apa pun. Perolehan token Azure AD yang gagal juga memunculkanAzureKeyVaultException.AzureKeyVaultSignermemvalidasi 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 denganAzureKeyVaultException.GcpKmsSignertanpa bearer token OAuth2 memunculkanSignatureFailedException; perolehan token adalah tanggung jawab pemanggil.- Respons provider yang bukan JSON valid, atau yang tidak memiliki field tanda tangan, memunculkan
SignatureFailedException(Azure: fieldvalueyang hilang memunculkanAzureKeyVaultException). - Field tanda tangan provider yang gagal decoding base64 memunculkan
SignatureFailedExceptionpada AWS dan GCP, danAzureKeyVaultExceptionpada Azure. - Tidak ada adapter
SigningStrategyuntukGcpKmsSigneryang dikirim pada 3.1.0. Signer GCP dikonsumsi melalui kontrakKmsSignerInterfacesecara langsung.
Perilaku mode-FIPS
Bagian berjudul “Perilaku mode-FIPS”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.
Konformitas
Bagian berjudul “Konformitas”| Klaim | Standar | Klausa |
|---|---|---|
| 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 3161 | Appendix 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.
Catatan pengembangan
Bagian berjudul “Catatan pengembangan”- Ketersediaan di dalam paket Pro:
AwsKmsSignersejak 1.9.0,AzureKeyVaultSignersejak 2.0.0,GcpKmsSignerdanKmsSignerInterfacesejak 2.1.0. Semuanya terkini dinextpdf/pro3.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
KmsSignerInterfacedan harus memberi namespace padaproviderId()-nya untuk menghindari tabrakan dengan identifier bawaan yang direservasi.
Lihat juga
Bagian berjudul “Lihat juga”- Penandatanganan Cloud KMS (kapabilitas) — halaman how-to: penyiapan, konfigurasi, dan batas key-custody.
- Keamanan — Referensi Mendalam —
RemoteSigningSession,SequentialSigner, permukaan PAdES B-B/B-T, dan kontrakSigningStrategy. - Tanda Tangan — Referensi Mendalam (Enterprise) — batas produsen jangka-panjang B-LT/B-LTA.
- Keamanan / Penandatanganan (Core) — signer CMS Core dan kontrak yang diperluas permukaan ini.
Batas publikasi
Bagian berjudul “Batas publikasi”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.