跳到內容
getnextpdf.com

Pro 版本

雲端 KMS 簽章 — 深入參考

本頁是 NextPDF Pro 雲端 KMS 簽章介面的契約層級參考。此介面由一個 Service Provider Interface NextPDF\Pro\Security\Signing\Kms\KmsSignerInterface 以及三個供應商簽章器組成:AwsKmsSignerAzureKeyVaultSignerGcpKmsSigner。兩個轉接器 AwsKmsSigningStrategyAzureKeyVaultSigningStrategy 將簽章器橋接至 Pro SigningStrategy 契約。每個簽章器僅透過 PSR-18 HTTP 將訊息摘要傳送給其供應商。私鑰與文件永不跨越此邊界。本頁載明公開 API、可觀察的行為契約,以及具型別的失敗模式。工作階段編排(RemoteSigningSessionSequentialSigner)與時間戳記(PadesBtTimestamper)位於各自的頁面。

此功能隨 NextPDF Pronextpdf/pro)提供,並以 Pro 等級授權封套啟用。未具備該授權的部署不會載入此功能的類別。比較版本並取得授權

符號參數預設行為回傳拋出或失敗於備註
KmsSignerInterface擴充 Core HsmSignerInterface 契約KMS 與 HSM 驅動程式的 SPI;保留的內建 id:aws-kmsazure-keyvaultgcp-kmspkcs11openssl-cli
KmsSignerInterface::providerId()none穩定的登錄查找鍵non-empty-string第三方驅動程式必須為其識別碼加上命名空間
KmsSignerInterface::signWithVersion()$data$algorithm = 'sha256WithRSAEncryption'$keyVersion = nullnull 金鑰版本會回退至供應商預設值string 簽章八位元組:RSA 依供應商回傳的形式(直接放入 SignerInfo.signature),ECDSA 依 CMS 規則以 DER ECDSA-Sig-Value 形式呈現KeyManagementExceptionUnsupportedAlgorithmExceptionSignatureFailedException各供應商的 null 語意不同;請參閱行為契約
KmsSignerInterface::supportsAlgorithm()string $algorithm能力探測;不執行任何 I/Obool於選擇供應商之前呼叫
KmsSignerInterface::supportedAlgorithms()none列出供應商接受的 OpenSSL 樣式名稱list<non-empty-string>
AwsKmsSigner建構子:AwsKmsConfig、憑證 DER、鏈 DER、PSR-18 用戶端、PSR-17 工廠、PSR-3 記錄器演算法預設為 KmsSigningAlgorithm::RsaPkcs1Sha256見各方法finalPROVIDER_ID = 'aws-kms'
AwsKmsSigner::create()金鑰 id、憑證 DER、PSR 相依項、選用的鏈、config、logger$confignull 時建構 AwsKmsConfig::fromEnvironment($keyId)self讀取標準的 AWS_* 環境變數
AwsKmsSigner::withAlgorithm()KmsSigningAlgorithm $algorithm回傳修改後的複本self必須符合 AWS KMS 中佈建的金鑰類型
AwsKmsSigner::sign()$data$algorithm = 'sha256WithRSAEncryption'委派給 signWithVersion($data, $algorithm, null)stringsignWithVersion()舊版雙引數 Core 契約路徑
AzureKeyVaultSigner建構子:AzureKeyVaultConfig、憑證 DER、鏈 DER、PSR-18 用戶端、PSR-17 工廠、PSR-3 記錄器演算法預設為 AzureSigningAlgorithm::Rs256;config 中的存取權杖會作為 bearer token 的種子見各方法finalPROVIDER_ID = 'azure-keyvault'
AzureKeyVaultSigner::create()vault 名稱、金鑰名稱、憑證 DER、PSR 相依項、選用的鏈、config、logger$confignull 時建構 AzureKeyVaultConfig::fromEnvironment()self支援預先取得的 token 或 service-principal 憑證
AzureKeyVaultSigner::withAlgorithm()AzureSigningAlgorithm $algorithm回傳修改後的複本selfRSA 金鑰使用 RS/PS 值;EC 金鑰使用 ES 值
GcpKmsSigner建構子:GcpKmsConfig、憑證 DER、鏈 DER、PSR-18 用戶端、PSR-17 工廠、PSR-3 記錄器演算法預設為 GcpKmsSigningAlgorithm::RsaSignPkcs1_2048Sha256見各方法finalPROVIDER_ID = 'gcp-kms'API_VERSION = 'v1'
GcpKmsSigner::create()專案 id、location、key ring、crypto key、憑證 DER、PSR 相依項、選用的鏈、config、logger$confignull 時建構 GcpKmsConfig::fromEnvironment()selfBearer token 的取得委派給呼叫端
GcpKmsSigner::withAlgorithm()GcpKmsSigningAlgorithm $algorithm僅為設定期預覽;簽章時以每次呼叫的 wire name 為準self金鑰大小由佈建的 CryptoKeyVersion 固定
AwsKmsSigningStrategy建構子:AwsKmsSigner $signer同步;isAsync() 回傳 false傳播所包裝簽章器的例外RemoteSigningSession::complete() 的轉接器
AzureKeyVaultSigningStrategy建構子:AzureKeyVaultSigner $signer同步;isAsync() 回傳 false傳播所包裝簽章器的例外RemoteSigningSession::complete() 的轉接器
KmsSigningAlgorithmenum,9 個案例(RSA PKCS#1、RSA-PSS、ECDSA;SHA-256/384/512)AWS KMS SigningAlgorithm wire 值來自 fromOpenSslName()InvalidArgumentExceptionresolveForWireName() 保留設定的 PSS 摘要
AzureSigningAlgorithmenum,9 個案例(RS256ES512Azure Key Vault JWA 樣式值來自 fromOpenSslName()InvalidArgumentExceptionisEcdsa() 標記其輸出需要 DER 轉換的值
GcpKmsSigningAlgorithmenum,10 個案例(EC P-256/P-384、RSA PKCS#1、RSA-PSS)GCP CryptoKeyVersion 演算法值來自 fromOpenSslName()UnsupportedAlgorithmExceptionWire 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'): 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 擴充 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 接受五個(sha256WithRSAEncryptionsha512WithRSAEncryptionRSASSA-PSSecdsa-with-SHA256ecdsa-with-SHA384)。RSASSA-PSS wire name 未編碼摘要,因此其摘要具有歧義。AwsKmsSigner 透過 KmsSigningAlgorithm::resolveForWireName() 解析它,該方法會保留所設定 PSS 變體的摘要。AzureKeyVaultSigner 對於此歧義名稱信任所設定的 PSS 變體。若解析出的 PSS 摘要會與所設定的不一致,則會拋出 UnsupportedAlgorithmExceptionGcpKmsSigner 在每次呼叫時都會從 wire name 重新解析 enum;GCP 上的 withAlgorithm() 是設定期預覽,不會改變簽章期的行為。不支援的 wire name 會在任何網路呼叫之前拋出 UnsupportedAlgorithmException。在 AwsKmsSignerGcpKmsSigner 上,一次簽章呼叫會將 getSigningAlgorithm() 之後回報的值更新為該次呼叫解析出的演算法。在 AzureKeyVaultSigner 上,解析為呼叫區域性,所設定的值仍具權威性。

AWS 與 GCP 以 CMS 可消費的形式回傳簽章:RSA 簽章八位元組原封不動地放入 SignerInfo.signature,而 ECDSA 以 DER 編碼形式抵達。Azure 以原始 IEEE P1363(r||s)形式回傳 ECDSA,簽章器會在回傳前將其轉換為 DER ECDSA-Sig-Value

SigningStrategy 轉接器會對工作階段所提供、經 DER 編碼的簽署屬性進行簽章。當簽署屬性存在時,CMS 簽章輸入為 SignedAttrs 值之完整 DER 編碼的摘要 — RFC 5652 §5.4。轉接器的 getSignatureAlgorithmOid()getDigestAlgorithm() 會供給 SignerInfo 的 signatureAlgorithmdigestAlgorithm 欄位 — 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 以繼承所設定的預設值。
  • 格式錯誤的金鑰版本會在建構任何請求之前被拒絕,並在例外中指出違規的值。
  • AwsKmsSignerAwsKmsConfig::$keyId 為空且金鑰版本為 null,則會拋出 KeyManagementException
  • 指出金鑰管理失敗的供應商回應會對映至 KeyManagementException:AWS NotFoundExceptionDisabledExceptionKeyUnavailableExceptionInvalidKeyUsageException 或 HTTP 404;Azure HTTP 404、KeyNotFoundKeyDisabledKeyNotActive;GCP HTTP 404 或 409、NOT_FOUNDFAILED_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 結構性字元的值會以 AzureKeyVaultException fail closed。
  • GcpKmsSigner 若無 OAuth2 bearer token,則會拋出 SignatureFailedException;權杖取得為呼叫端的責任。
  • 非有效 JSON 或缺少 signature 欄位的供應商回應會拋出 SignatureFailedException(Azure:缺少 value 欄位會拋出 AzureKeyVaultException)。
  • base64 解碼失敗的供應商 signature 欄位在 AWS 與 GCP 上會拋出 SignatureFailedException,在 Azure 上則拋出 AzureKeyVaultException
  • 3.1.0 中未提供 GcpKmsSignerSigningStrategy 轉接器。GCP 簽章器直接透過 KmsSignerInterface 契約使用。

AwsKmsConfig::withFipsEndpoint() 會將請求路由至該區域的 kms-fips 端點。該端點的 FIPS 驗證狀態是 AWS 的屬性,而非 NextPDF 的屬性。AzureKeyVaultConfigGcpKmsConfig 在 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 3161Appendix A

所有條款皆為改寫;NextPDF 不重現規範性文字。這些是能力聲明,而非認證。NextPDF 未持有任何認證,亦不授予任何認證。產生的簽章是否通過驗證,是驗證者依其自身信任錨與政策所作的決定;簽章器回傳簽章位元組,並不主張任何受信任的結果。金鑰保管、金鑰保護與供應商端的演算法驗證是所設定 KMS 的屬性,而非 NextPDF 的屬性。

  • Pro 套件內的可用性:AwsKmsSigner 自 1.9.0 起,AzureKeyVaultSigner 自 2.0.0 起,GcpKmsSignerKmsSignerInterface 自 2.1.0 起。全部在 nextpdf/pro 3.1.0 中為現行版本。
  • 這些簽章器僅相依於 PSR-18、PSR-17 與 PSR-3。不需要也不隨附任何 AWS、Azure 或 Google SDK。
  • 在簽章前先探測 supportsAlgorithm(),讓不相容的供應商在選擇時即被拒絕,而非在工作階段中途。
  • 憑證欄位以建構子注入並標記為敏感參數。記錄訊息僅攜帶結構性欄位;不會將任何憑證、權杖或文件內容寫入記錄。
  • 在受監管的部署中明確釘選金鑰版本。別名解析(AWS)與最新啟用(Azure)的預設值雖然便利,但在輪替之間並非具決定性。
  • 第三方驅動程式實作 KmsSignerInterface,並必須為其 providerId() 加上命名空間,以避免與保留的內建識別碼發生衝突。

本頁僅記載外部可觀察的行為與受支援的公開 API 介面。內部命名空間路徑、輔助類別、機制表、runbook 檔名與工單前綴皆不在範圍內。