跳到內容

HSM 支援的簽署

Spec: ISO 32000-2, §12.8 Spec: FIPS 140-3 Evidence: Standard-backed

硬體安全模組(HSM)會把簽署金鑰移出你的行程,放到一個只依請求簽署、但絕不交還金鑰的裝置後面。本頁說明 NextPDF 透過哪一道 PKCS#11 接縫簽署、金鑰邊界究竟落在哪裡,以及成品中哪些部分由引擎負責,而不是由裝置或你負責。

位於行程記憶體中的簽署金鑰,任何能讀取該行程的東西都能讀到:一份 heap dump、一個除錯器、一次記錄失誤、一個有漏洞的相依套件。一旦私鑰被複製,它先前產生的每一份簽章都會受到質疑,而且你無法收回這次外洩。HSM 的重點在於:根本沒有副本可拿。

把邊界弄錯,代價會悄悄累積。一個看起來由硬體支援、卻把金鑰拉進記憶體簽署的工作流程,承擔了 HSM 的營運成本,卻只有軟體金鑰的風險樣貌。這項差異從完成後的 PDF 看不出來,因此必須在設計中明確劃定並驗證,不能只靠假設。

  • PKCS#11 標準定義了一種被標記為敏感且不可匯出的金鑰物件。它的私有值無法在 token 之外以明文揭露 Spec: PKCS#11, v3.1 §10.9
  • NextPDF 建構 PDF 簽章結構與 CMS 容器。它會將要簽署的位元組送過 PKCS#11 接縫,再收回簽章。金鑰絕不跨越那道接縫。
  • 這道接縫是一份穩定的合約。智慧卡 token、USB HSM、網路 HSM,以及雲端 KMS,全都遵循同一份合約。引擎程式碼在它們之間不會改變。
  • NextPDF 是簽署引擎軟體。裝置的硬體保證、驗證狀態、PIN 政策,以及部署方式,都不是引擎所認證的事項。它使用該裝置,但並不為它背書。

NextPDF 把組裝一份簽章計算簽章值分開。組裝由引擎負責:放置簽章欄位、在檔案中保留空間、計算位元組範圍,並建構帶有已簽署屬性的 CMS SignedData Spec: ISO 32000-2, §12.8

計算簽章值則委派出去。引擎定義了一份精簡的簽署提供者合約:它接收一段不透明位元組字串(實務上即 DER 編碼的已簽署屬性),並回傳原始的簽章八位元組。那份合約就是接縫。一側是 PDF 與 CMS 的處理邏輯;另一側是一把金鑰。提供者可能在行程內持有一把本地軟體金鑰、把金鑰放在雲端 KMS 中,或透過 PKCS#11 將金鑰保留在硬體 token 上。接縫之上的引擎程式碼在每一種情況下都完全相同。只有它背後的提供者不同。

PKCS#11——也就是 OASIS 加密 token 介面,歷史上稱為「Cryptoki」—— 是存取硬體 token 的標準 C 介面。NextPDF 的硬體路徑透過 PKCS#11 溝通(直接溝通,或在 engine 或 provider 部署中,當行程內繫結無法載入 token 時,透過 OpenSSL 命令列橋接溝通)。

token 上的金鑰物件建立時,會帶有兩個界定邊界的屬性。當金鑰被標記為敏感或不可匯出時,某些私有屬性無法在 token 之外以明文揭露 Spec: PKCS#11, v3.1 §10.9 簽署作業本身發生在 token 呼叫中——先 C_SignInitC_Sign——由裝置執行。 Spec: PKCS#11, v3.1 §5.10 進入 NextPDF 的明文,是要簽署的位元組。回來的是簽章與憑證。私鑰不在任一條路徑上。那就是邊界,而強制執行它的是 token,並非函式庫。

  1. Step 1 of 4: ISO 32000-2 §12.8 — signature dictionary, ByteRange, Contents
  2. Step 2 of 4: RFC 5652 CMS SignedData — the signature container
  3. Step 4 of 4: FIPS 140-3 / ISO/IEC 19790 cryptographic module assurance (device-level, deployment-dependent)
依序說明一份由硬體支援的 PDF 簽章奠基於何處:PDF 載體(ISO 32000-2 §12.8)、它所承載的 CMS 容器、NextPDF 透過以簽署的 token 介面(PKCS#11),以及那些描述——但本身並不保證——其背後裝置的模組保證標準。

PKCS#11 允許一把金鑰在每次使用時要求重新驗證:當 CKA_ALWAYS_AUTHENTICATE 屬性被設定時,使用者必須再次出示 PIN 於每一次加密作業,而不是每個工作階段一次。 Spec: PKCS#11, v3.1 §10.9 NextPDF 的 PKCS#11 路徑就是為此而寫的。PIN 是一項敏感參數。它不會被記錄或序列化。當某個工作階段回報既有登入狀態時,NextPDF 會將其重設為乾淨狀態,好讓下一份簽章取得一次全新的 PIN 檢查。這對於政策要求每份簽章都需一次 PIN 的 PIV 式 token 而言很重要。這是尊重裝置政策的引擎行為;它並不放寬該政策。

Evidence: Standard-backed 不可匯出金鑰的性質,並不是 NextPDF 自己的主張。它出自 PKCS#11 模型:一個金鑰物件,其 CKA_SENSITIVE 為真,或 CKA_EXTRACTABLE 為偽時,不會交出其在 token 之外的明文私有值。 Spec: PKCS#11, v3.1 §10.9 NextPDF 的做法是永遠不需要那個值:它透過 token 的 C_Sign 作業簽署,而非索取金鑰素材。

Evidence: Standard-backed PDF 這一側依據 Spec: ISO 32000-2, §12.8 。位元組範圍摘要是在排除簽章值的檔案上計算而得。放入 Contents 項目中的簽章值,對公開金鑰簽章而言是一個 DER 編碼的 CMS SignedData 物件, 如上所述。HSM 只產出最內層的簽章八位元組。 NextPDF 圍繞它們建構其餘一切,並把它們寫入標準所定義的結構之中。

Evidence: Standard-backed 裝置保證由 Spec: FIPS 140-3 及其基礎標準 ISO/IEC 19790 描述,這些標準涵蓋十一個需求領域,定義了四個遞增的定性安全等級 ——從演算法規範,到實體竄改證據。這些標準描述一個模組必須滿足什麼,才能主張某個等級。它們是裝置及其驗證的性質,而非 NextPDF 的性質,而且——以 ISO/IEC 19790 本身的說法——符合性本身並不足以 確保某個模組在特定部署中是安全的。

下方的樣貌僅供說明。它呈現的是接縫,而非可直接複製貼上的部署。重點在於:引擎拿到的是一個簽署者,而不是金鑰;該簽署者的 sign() 是一次進入裝置的呼叫。

<?php
declare(strict_types=1);
use NextPDF\Contracts\HsmSignerInterface;
/**
* Sign a PDF where the private key lives on a PKCS#11 token.
*
* `$hsm` is a hardware-backed signer. Its sign() delegates to the token;
* the key never enters this process. Everything that makes the bytes a
* valid PDF signature — field, byte range, CMS SignedData — is built by
* the engine around the value the device returns.
*
* Token wiring (library path, slot, PIN, key label) is deployment
* configuration and is intentionally out of scope here: those values are
* operator-owned secrets, not library inputs to hardcode.
*/
function signWithToken(
string $pdfPath,
HsmSignerInterface $hsm,
): string {
// The engine asks the signer only for: the certificate (to embed in
// the CMS) and a signature over the bytes it computes. It never asks
// for, and the contract never exposes, the private key.
$certificateDer = $hsm->getCertificateDer();
$chainDer = $hsm->getCertificateChainDer();
// Pseudocode for the engine's own assembly step: build the signature
// dictionary + CMS SignedData, then hand the signed-attributes bytes
// to $hsm->sign(...) and place the returned octets in /Contents.
return nextpdf_sign_pdf(
pdfPath: $pdfPath,
signer: $hsm,
certificateDer: $certificateDer,
chainDer: $chainDer,
);
}

關於這個樣貌,有兩點需要說清楚。行程內的 PKCS#11 繫結,是標準 PHP 建置並不包含的獨立 PHP 擴充。硬體部署必須把它作為平台的一部分安裝並驗證(或使用 OpenSSL 命令列橋接),而不是事後補上。而且,向裝置要求的演算法,必須是該金鑰實際能執行的演算法。當所設定的演算法對所選提供者沒有對應時,引擎會提早拒絕,而不是拖到某次 token 呼叫深處才失敗。

「使用 HSM 就代表簽署通過了 FIPS 驗證。」

並非如此,把兩者混為一談正是那個陷阱。HSM 是金鑰所在、作業執行的地點FIPS 140-3 / ISO/IEC 19790 驗證是裝置(或某個特定模組組態)可能持有的一項性質,由某個驗證計畫確立——既不是某個呼叫端函式庫所授予的,也不是 NextPDF 代裝置所主張的。NextPDF 相容於透過 PKCS#11 裝置簽署,且其簽署路徑已具代表性類別的 token 測試過。某個特定部署是否達到FIPS 模組等級驗證,完全取決於硬體、其憑證,以及它如何被組態與操作。請用精確的字詞,描述你實際擁有的東西。

本頁描述這道接縫,以及它所依據的標準。它不是一份部署保證,而這條界線值得明白地說清楚:

  • 引擎的職責。 建構簽章欄位、保留空間、計算位元組範圍、組裝 CMS SignedData、呼叫簽署提供者,並依 Spec: ISO 32000-2, §12.8 寫出一份結構正確的簽章。NextPDF 的硬體路徑就此目的而言符合 PKCS#11 簽署介面。
  • 裝置與操作者的職責。 硬體的抗竄改能力、其 FIPS 140-3 / ISO/IEC 19790 驗證狀態、金鑰產生與保管、PIN 政策、插槽組態、韌體,以及實體安全。這些都不是引擎所認證的事項。
  • 「測試過」不等於「已認證」。 NextPDF 針對具代表性的 token 類別——智慧卡、USB、網路,以及透過同一份 PKCS#11 合約所觸及的雲端 KMS 樣貌——擁有一條已驗證的路徑,這是一項相容性聲明。它並非一項認證、一份已驗證模組的計數,也並非對你特定裝置的主張。下方的硬體類別,是透過同一個標準介面的整合樣貌。請將它們視為「接縫已被演練之處」,絕不可當成對你尚未自行測試的型號的保證。
  • 後量子簽署仍屬實驗性。 當引擎透過某個 token 提供後量子簽署時,它是選擇加入、受到把關,且驗證對象是 mock,而不是後量子 HSM 韌體。PAdESAdES 的加密套件目錄,尚未將那些套件納入長期封存的認可範圍。請勿將它視為可用於生產環境。
HSM-backed signing via PKCS#11 — edition availability
Edition Availability
Core

此版本不提供。Core 提供簽署引擎與簽署提供者接縫,並附帶一個本地軟體金鑰提供者。

Pro

雲端金鑰管理——透過受管 KMS 金鑰簽署——是 Pro 的能力,僅在行為層級加以描述。

Enterprise

提供。透過 PKCS#11 介面的硬體 token 簽署(以及供 engine/provider 部署使用的 OpenSSL 命令列橋接)是 Enterprise 的能力。「提供」是一項能力聲明,而非對任何裝置或部署的認證。

以下是 PKCS#11 接縫被演練過的樣貌。此欄說明「整合看起來的樣子」,而非「一份已驗證、已認證或計數過的裝置清單」。

整合樣貌如何連接金鑰邊界保證屬於誰
智慧卡 / PIV tokenPKCS#11 模組;常見做法是每次使用需 PIN在卡片上;不可匯出卡片及其操作者
USB HSMPKCS#11 模組在裝置上;不可匯出裝置及其操作者
網路 / 設備型 HSMPKCS#11 模組連往一個網路裝置在設備上;不可匯出設備、其組態,以及操作者
雲端 KMS受管金鑰提供者(Pro)在雲端服務中;從不回傳雲端提供者及其證明
OpenSSL 提供者橋接透過 OpenSSL 橋接的 PKCS#11在 token 上;不可匯出token 及其操作者
小型常見問答

金鑰會進入 PHP 行程嗎? 不會。對一把不可匯出的 PKCS#11 金鑰而言,其私有值無法在 token 之外以明文揭露。NextPDF 透過 token 作業簽署,而且只看得到要簽署的位元組與回傳的簽章。

由 HSM 支援的簽章,在 PDF 內部會不同嗎? 不會。簽章結構是同一個 CMS SignedData,位於同一個 Contents 項目中,涵蓋同一個位元組範圍。HSM 改變的是簽署發生在何處,而非磁碟上的樣貌。

因為我透過 NextPDF 使用了 HSM,我能主張 FIPS 合規嗎? 只能非常審慎地這麼做。NextPDF 對裝置的 FIPS 狀態不作任何主張。任何此類主張都必須來自裝置自身的驗證及其部署方式,而非源自 NextPDF 呼叫了它這個事實。

如果行程內的 PKCS#11 繫結無法使用呢? 引擎會回報硬體簽署不可用,而非悄悄退回到軟體金鑰。若部署環境的行程內繫結無法載入 token,另有一條 OpenSSL 命令列橋接路徑。

  • HSM(硬體安全模組)——一種經強化的裝置,持有金鑰並執行加密作業,使金鑰素材永不離開它。
  • PKCS#11——OASIS 加密 token 介面標準(歷史上稱為「Cryptoki」);NextPDF 用來與硬體 token 溝通的 C 介面。
  • 不可匯出金鑰——一個 PKCS#11 金鑰物件,其私有值無法在 token 之外以明文揭露(CKA_SENSITIVE 為真,或 CKA_EXTRACTABLE 為偽)。
  • 接縫——NextPDF 中的簽署提供者邊界:不透明位元組進,簽章八位元組出。PDF 與 CMS 的處理邏輯位於它之上;金鑰位於它之後。
  • CMS SignedData——加密訊息語法結構(RFC 5652),在 PDF 內部承載簽章與憑證。
  • FIPS 140-3 / ISO/IEC 19790——定義四個定性等級的加密模組安全標準;這是裝置及其驗證的性質,而非某個呼叫端函式庫的性質。