Pro 版本
雲端 KMS 簽章 — 深入參考
本頁是 NextPDF Pro 雲端 KMS 簽章介面的契約層級參考。此介面由一個 Service Provider Interface NextPDF\Pro\Security\Signing\Kms\KmsSignerInterface 以及三個供應商簽章器組成:AwsKmsSigner、AzureKeyVaultSigner 與 GcpKmsSigner。兩個轉接器 AwsKmsSigningStrategy 與 AzureKeyVaultSigningStrategy 將簽章器橋接至 Pro SigningStrategy 契約。每個簽章器僅透過 PSR-18 HTTP 將訊息摘要傳送給其供應商。私鑰與文件永不跨越此邊界。本頁載明公開 API、可觀察的行為契約,以及具型別的失敗模式。工作階段編排(RemoteSigningSession、SequentialSigner)與時間戳記(PadesBtTimestamper)位於各自的頁面。
可用性與授權
標題為「可用性與授權」的區段此功能隨 NextPDF Pro(nextpdf/pro)提供,並以 Pro 等級授權封套啟用。未具備該授權的部署不會載入此功能的類別。比較版本並取得授權。
公開 API 介面
標題為「公開 API 介面」的區段| 符號 | 參數 | 預設行為 | 回傳 | 拋出或失敗於 | 備註 |
|---|---|---|---|---|---|
KmsSignerInterface | — | 擴充 Core HsmSignerInterface 契約 | — | — | KMS 與 HSM 驅動程式的 SPI;保留的內建 id:aws-kms、azure-keyvault、gcp-kms、pkcs11、openssl-cli |
KmsSignerInterface::providerId() | none | 穩定的登錄查找鍵 | non-empty-string | — | 第三方驅動程式必須為其識別碼加上命名空間 |
KmsSignerInterface::signWithVersion() | $data、$algorithm = 'sha256WithRSAEncryption'、$keyVersion = null | null 金鑰版本會回退至供應商預設值 | string 簽章八位元組:RSA 依供應商回傳的形式(直接放入 SignerInfo.signature),ECDSA 依 CMS 規則以 DER ECDSA-Sig-Value 形式呈現 | KeyManagementException、UnsupportedAlgorithmException、SignatureFailedException | 各供應商的 null 語意不同;請參閱行為契約 |
KmsSignerInterface::supportsAlgorithm() | string $algorithm | 能力探測;不執行任何 I/O | bool | — | 於選擇供應商之前呼叫 |
KmsSignerInterface::supportedAlgorithms() | none | 列出供應商接受的 OpenSSL 樣式名稱 | list<non-empty-string> | — | — |
AwsKmsSigner | 建構子:AwsKmsConfig、憑證 DER、鏈 DER、PSR-18 用戶端、PSR-17 工廠、PSR-3 記錄器 | 演算法預設為 KmsSigningAlgorithm::RsaPkcs1Sha256 | — | 見各方法 | final;PROVIDER_ID = 'aws-kms' |
AwsKmsSigner::create() | 金鑰 id、憑證 DER、PSR 相依項、選用的鏈、config、logger | 當 $config 為 null 時建構 AwsKmsConfig::fromEnvironment($keyId) | self | — | 讀取標準的 AWS_* 環境變數 |
AwsKmsSigner::withAlgorithm() | KmsSigningAlgorithm $algorithm | 回傳修改後的複本 | self | — | 必須符合 AWS KMS 中佈建的金鑰類型 |
AwsKmsSigner::sign() | $data、$algorithm = 'sha256WithRSAEncryption' | 委派給 signWithVersion($data, $algorithm, null) | string | 同 signWithVersion() | 舊版雙引數 Core 契約路徑 |
AzureKeyVaultSigner | 建構子:AzureKeyVaultConfig、憑證 DER、鏈 DER、PSR-18 用戶端、PSR-17 工廠、PSR-3 記錄器 | 演算法預設為 AzureSigningAlgorithm::Rs256;config 中的存取權杖會作為 bearer token 的種子 | — | 見各方法 | final;PROVIDER_ID = 'azure-keyvault' |
AzureKeyVaultSigner::create() | vault 名稱、金鑰名稱、憑證 DER、PSR 相依項、選用的鏈、config、logger | 當 $config 為 null 時建構 AzureKeyVaultConfig::fromEnvironment() | self | — | 支援預先取得的 token 或 service-principal 憑證 |
AzureKeyVaultSigner::withAlgorithm() | AzureSigningAlgorithm $algorithm | 回傳修改後的複本 | self | — | RSA 金鑰使用 RS/PS 值;EC 金鑰使用 ES 值 |
GcpKmsSigner | 建構子:GcpKmsConfig、憑證 DER、鏈 DER、PSR-18 用戶端、PSR-17 工廠、PSR-3 記錄器 | 演算法預設為 GcpKmsSigningAlgorithm::RsaSignPkcs1_2048Sha256 | — | 見各方法 | final;PROVIDER_ID = 'gcp-kms'、API_VERSION = 'v1' |
GcpKmsSigner::create() | 專案 id、location、key ring、crypto key、憑證 DER、PSR 相依項、選用的鏈、config、logger | 當 $config 為 null 時建構 GcpKmsConfig::fromEnvironment() | self | — | Bearer token 的取得委派給呼叫端 |
GcpKmsSigner::withAlgorithm() | GcpKmsSigningAlgorithm $algorithm | 僅為設定期預覽;簽章時以每次呼叫的 wire name 為準 | self | — | 金鑰大小由佈建的 CryptoKeyVersion 固定 |
AwsKmsSigningStrategy | 建構子:AwsKmsSigner $signer | 同步;isAsync() 回傳 false | — | 傳播所包裝簽章器的例外 | RemoteSigningSession::complete() 的轉接器 |
AzureKeyVaultSigningStrategy | 建構子:AzureKeyVaultSigner $signer | 同步;isAsync() 回傳 false | — | 傳播所包裝簽章器的例外 | RemoteSigningSession::complete() 的轉接器 |
KmsSigningAlgorithm | enum,9 個案例(RSA PKCS#1、RSA-PSS、ECDSA;SHA-256/384/512) | — | AWS KMS SigningAlgorithm wire 值 | 來自 fromOpenSslName() 的 InvalidArgumentException | resolveForWireName() 保留設定的 PSS 摘要 |
AzureSigningAlgorithm | enum,9 個案例(RS256…ES512) | — | Azure Key Vault JWA 樣式值 | 來自 fromOpenSslName() 的 InvalidArgumentException | isEcdsa() 標記其輸出需要 DER 轉換的值 |
GcpKmsSigningAlgorithm | enum,10 個案例(EC P-256/P-384、RSA PKCS#1、RSA-PSS) | — | GCP CryptoKeyVersion 演算法值 | 來自 fromOpenSslName() 的 UnsupportedAlgorithmException | Wire name 解析選擇最小的相符金鑰大小 |
進入點簽名
標題為「進入點簽名」的區段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): string行為契約
標題為「行為契約」的區段契約解析
標題為「契約解析」的區段KmsSignerInterface 擴充 Core HsmSignerInterface 契約。它新增了 providerId()、可感知金鑰版本的 signWithVersion(),以及 supportsAlgorithm() 與 supportedAlgorithms() 能力探測。繼承而來的雙引數 sign() 在三個簽章器上皆以 null 金鑰版本委派給 signWithVersion()。getCertificateDer()、getCertificateChainDer() 與 getPublicKeyAlgorithm() 由建構子所提供的材料實作。能力探測不執行任何 I/O。每個簽章器另外提供 getSigningAlgorithm() 與 getConfig() 存取器供檢視。
僅傳輸摘要
標題為「僅傳輸摘要」的區段每個簽章器在本機以解析出的演算法摘要對 $data 進行雜湊,並僅傳輸該摘要。AWS 收到帶有 MessageType: DIGEST 的 base64 摘要。Azure 在簽章請求主體中收到 base64url 摘要。GCP 在演算法特定的摘要欄位中收到 base64 摘要。文件位元組永不出現在供應商請求中。所有傳輸皆使用標準 PSR-18 HTTP 用戶端透過供應商的 HTTPS 端點進行;不涉及任何雲端廠商 SDK。
金鑰版本解析
標題為「金鑰版本解析」的區段signWithVersion() 在建構任何請求之前,以 fail-closed 方式驗證金鑰版本引數。未通過供應商語法的值會拋出 KeyManagementException,並防止 URL 區段或 KeyId 注入。
| 供應商 | null 金鑰版本 | 空字串 | 覆寫語法 |
|---|---|---|---|
AwsKmsSigner | 使用 AwsKmsConfig::$keyId;別名或 ARN 會在供應商端解析為目前的金鑰 | 拒絕 | UUID(含或不含連字號)、alias/<name>,或 KMS 金鑰/別名 ARN |
AzureKeyVaultSigner | 使用設定的金鑰版本;空的 config 值會在伺服器端選擇最新啟用的版本 | 拒絕 | 32 個字元的十六進位識別碼 |
GcpKmsSigner | 使用 GcpKmsConfig 中釘選的版本;若未釘選任何版本,則拋出 KeyManagementException | 拒絕 | 十進位 CryptoKeyVersion id,僅限數字 |
GCP 沒有伺服器端的「作用中版本」原語。非對稱簽章端點僅在特定的 cryptoKeyVersions/{n} 資源上運作,因此版本必須永遠可解析。
演算法解析
標題為「演算法解析」的區段策略層會轉發 OpenSSL 樣式的 wire name。AWS 與 Azure 接受七個 wire name(SHA-256/384/512 的 PKCS#1 與 ECDSA,外加 RSASSA-PSS)。GCP 接受五個(sha256WithRSAEncryption、sha512WithRSAEncryption、RSASSA-PSS、ecdsa-with-SHA256、ecdsa-with-SHA384)。RSASSA-PSS wire name 未編碼摘要,因此其摘要具有歧義。AwsKmsSigner 透過 KmsSigningAlgorithm::resolveForWireName() 解析它,該方法會保留所設定 PSS 變體的摘要。AzureKeyVaultSigner 對於此歧義名稱信任所設定的 PSS 變體。若解析出的 PSS 摘要會與所設定的不一致,則會拋出 UnsupportedAlgorithmException。GcpKmsSigner 在每次呼叫時都會從 wire name 重新解析 enum;GCP 上的 withAlgorithm() 是設定期預覽,不會改變簽章期的行為。不支援的 wire name 會在任何網路呼叫之前拋出 UnsupportedAlgorithmException。在 AwsKmsSigner 與 GcpKmsSigner 上,一次簽章呼叫會將 getSigningAlgorithm() 之後回報的值更新為該次呼叫解析出的演算法。在 AzureKeyVaultSigner 上,解析為呼叫區域性,所設定的值仍具權威性。
簽章正規化
標題為「簽章正規化」的區段AWS 與 GCP 以 CMS 可消費的形式回傳簽章:RSA 簽章八位元組原封不動地放入 SignerInfo.signature,而 ECDSA 以 DER 編碼形式抵達。Azure 以原始 IEEE P1363(r||s)形式回傳 ECDSA,簽章器會在回傳前將其轉換為 DER ECDSA-Sig-Value。
CMS 整合與相鄰面
標題為「CMS 整合與相鄰面」的區段SigningStrategy 轉接器會對工作階段所提供、經 DER 編碼的簽署屬性進行簽章。當簽署屬性存在時,CMS 簽章輸入為 SignedAttrs 值之完整 DER 編碼的摘要 — RFC 5652 §5.4。轉接器的 getSignatureAlgorithmOid() 與 getDigestAlgorithm() 會供給 SignerInfo 的 signatureAlgorithm 與 digestAlgorithm 欄位 — RFC 5652 §5.3。回傳的位元組會成為 SignerInfo signature OCTET STRING — RFC 5652 §5.5。CMS 組裝、ByteRange 處理與工作階段生命週期屬於 RemoteSigningSession;多方流程屬於 SequentialSigner。PAdES B-T 簽章時間戳記(其 messageImprint 會對 SignerInfo signature 值進行雜湊 — RFC 3161 Appendix A)由 PadesBtTimestamper 施加,而非由這些簽章器施加。這三者皆記載於 Pro 安全性深度參考。
邊界情況與失敗模式
標題為「邊界情況與失敗模式」的區段- 空字串金鑰版本在三個供應商上皆會被拒絕。傳入
null以繼承所設定的預設值。 - 格式錯誤的金鑰版本會在建構任何請求之前被拒絕,並在例外中指出違規的值。
AwsKmsSigner若AwsKmsConfig::$keyId為空且金鑰版本為null,則會拋出KeyManagementException。- 指出金鑰管理失敗的供應商回應會對映至
KeyManagementException:AWSNotFoundException、DisabledException、KeyUnavailableException、InvalidKeyUsageException或 HTTP 404;Azure HTTP 404、KeyNotFound、KeyDisabled或KeyNotActive;GCP HTTP 404 或 409、NOT_FOUND、FAILED_PRECONDITION,或訊息中指名版本的 HTTP 400。 - 其他非 200 的供應商回應在 AWS 與 GCP 上會拋出
SignatureFailedException,在 Azure 上則拋出AzureKeyVaultException。 - 簽章期間的 PSR-18 傳輸失敗會對映至
SignatureFailedException,並將用戶端例外保留為前一個 throwable。 AzureKeyVaultSigner若既無存取權杖亦無 service-principal 憑證,則會在任何 vault 呼叫之前拋出AzureKeyVaultException。Azure AD 權杖取得失敗同樣會拋出AzureKeyVaultException。AzureKeyVaultSigner會在請求瓶頸處,依據 Azure 已發布的語法驗證 vault 名稱、金鑰名稱、金鑰版本與 tenant id。帶有 URL 結構性字元的值會以AzureKeyVaultExceptionfail closed。GcpKmsSigner若無 OAuth2 bearer token,則會拋出SignatureFailedException;權杖取得為呼叫端的責任。- 非有效 JSON 或缺少 signature 欄位的供應商回應會拋出
SignatureFailedException(Azure:缺少value欄位會拋出AzureKeyVaultException)。 - base64 解碼失敗的供應商 signature 欄位在 AWS 與 GCP 上會拋出
SignatureFailedException,在 Azure 上則拋出AzureKeyVaultException。 - 3.1.0 中未提供
GcpKmsSigner的SigningStrategy轉接器。GCP 簽章器直接透過KmsSignerInterface契約使用。
FIPS 模式行為
標題為「FIPS 模式行為」的區段AwsKmsConfig::withFipsEndpoint() 會將請求路由至該區域的 kms-fips 端點。該端點的 FIPS 驗證狀態是 AWS 的屬性,而非 NextPDF 的屬性。AzureKeyVaultConfig 與 GcpKmsConfig 在 3.1.0 中未提供專用的 FIPS 端點輔助方法。摘要計算以 PHP hash() 函式在行程內執行,其本身並非經驗證的模組。NextPDF Pro 可針對通過 FIPS 驗證的 KMS 或 HSM 邊界運作,但 NextPDF 並非通過 FIPS 驗證的密碼模組,亦不提出任何 FIPS 認證主張。
符合性
標題為「符合性」的區段| 主張 | 標準 | 條款 |
|---|---|---|
| 策略會對經 DER 編碼的簽署屬性進行簽章;CMS 簽章輸入摘要涵蓋 SignedAttrs 的完整 DER 編碼。 | RFC 5652 | §5.4 |
| SignedAttributes 經 DER 編碼,且至少攜帶 content-type 與 message-digest;signatureAlgorithm 標識簽章者的演算法。 | RFC 5652 | §5.3 |
| 回傳的簽章位元組編碼為 OCTET STRING,並攜帶於 SignerInfo signature 欄位中。 | RFC 5652 | §5.5 |
| 簽章時間戳記的 messageImprint 會對 SignerInfo signature 值進行雜湊(相鄰的 B-T 介面,非這些簽章器)。 | RFC 3161 | Appendix A |
所有條款皆為改寫;NextPDF 不重現規範性文字。這些是能力聲明,而非認證。NextPDF 未持有任何認證,亦不授予任何認證。產生的簽章是否通過驗證,是驗證者依其自身信任錨與政策所作的決定;簽章器回傳簽章位元組,並不主張任何受信任的結果。金鑰保管、金鑰保護與供應商端的演算法驗證是所設定 KMS 的屬性,而非 NextPDF 的屬性。
開發備註
標題為「開發備註」的區段- Pro 套件內的可用性:
AwsKmsSigner自 1.9.0 起,AzureKeyVaultSigner自 2.0.0 起,GcpKmsSigner與KmsSignerInterface自 2.1.0 起。全部在nextpdf/pro3.1.0 中為現行版本。 - 這些簽章器僅相依於 PSR-18、PSR-17 與 PSR-3。不需要也不隨附任何 AWS、Azure 或 Google SDK。
- 在簽章前先探測
supportsAlgorithm(),讓不相容的供應商在選擇時即被拒絕,而非在工作階段中途。 - 憑證欄位以建構子注入並標記為敏感參數。記錄訊息僅攜帶結構性欄位;不會將任何憑證、權杖或文件內容寫入記錄。
- 在受監管的部署中明確釘選金鑰版本。別名解析(AWS)與最新啟用(Azure)的預設值雖然便利,但在輪替之間並非具決定性。
- 第三方驅動程式實作
KmsSignerInterface,並必須為其providerId()加上命名空間,以避免與保留的內建識別碼發生衝突。
另請參閱
標題為「另請參閱」的區段- 雲端 KMS 簽章(功能) — 操作指南頁面:設定、組態與金鑰保管邊界。
- 安全性 — 深度參考 —
RemoteSigningSession、SequentialSigner、PAdES B-B/B-T 介面,以及SigningStrategy契約。 - 簽章 — 深度參考(Enterprise) — B-LT/B-LTA 長期產生器邊界。
- 安全性 / 簽章(Core) — Core CMS 簽章器以及此介面所擴充的契約。
發布邊界
標題為「發布邊界」的區段本頁僅記載外部可觀察的行為與受支援的公開 API 介面。內部命名空間路徑、輔助類別、機制表、runbook 檔名與工單前綴皆不在範圍內。