跳到內容
getnextpdf.com

Enterprise 版本

Security — 深入參考(HSM、PKCS#11、FIPS 模式)

本頁是 NextPDF Enterprise 安全範圍的整合深入參考。它涵蓋透過 PKCS#11 的硬體 token 簽署、透過 OpenSSL 命令列介面(CLI)的子程序簽署、FIPS 密碼學原則預設、執行階段 FIPS 守衛,以及開機自我測試守衛。另有兩份聚焦的搭配文件:HSM — 深入參考 提供簽署器細節,以及 FIPS 140 — 深入參考 提供 FIPS 模組細節。後量子簽署路徑為預覽,不做任何符合性聲明。NextPDF 未持有任何認證,亦不授予任何認證;支援不等於符合,符合不等於認證。

此功能隨 NextPDF Enterprisenextpdf/enterprise)出貨,並以 Enterprise 層級授權封套啟用。未具該權利的部署不會載入此功能的類別。比較版本並取得授權

Terminal window
composer require nextpdf/enterprise:^3

簽署型別位於 NextPDF\Enterprise\Security\Signature\Hsm;FIPS 型別位於 NextPDF\Enterprise\Security\Fips;組合根位於 NextPDF\Enterprise\Bootstrap。兩個簽署器都實作 Core 的 NextPDF\Contracts\HsmSignerInterface 合約。該原則實作 Core 的 NextPDF\Contracts\CryptoPolicyInterfaceNextPDF\Contracts\PreOperationalSelfTestInterface 合約。

符號參數預設行為回傳拋出或失敗於備註
Pkcs11Signer::__construct()string $libraryPath, int $slotId, string $pin, string $certLabel, ?string $keyLabel = null, array $chainDer = [], bool $enablePostQuantum = false, ?FipsSignatureEnforcer $fipsEnforcer = null開啟廠商函式庫、登入 slot、載入憑證與金鑰演算法中繼資料ext-pkcs11 不存在或 token 存取失敗時拋出 HsmOperationExceptionPIN 與標籤為 #[SensitiveParameter];每個程序中每個函式庫路徑快取一個模組控制代碼
Pkcs11Signer::isAvailable()回報是否已載入 ext-pkcs11bool靜態;於建構前檢查
Pkcs11Signer::sign()string $data, string $algorithm = 'sha256WithRSAEncryption'在 token 上簽署;原始 ECDSA 輸出會轉換為 DER ECDSA-Sig-Valuestring 原始簽章位元組HsmOperationException(找不到金鑰、token 失敗);InvalidArgumentException(未對應的演算法);當接上 enforcer 時於簽署前拋出 FipsViolationException / FipsModuleErrorStateException封閉演算法集合;見〈行為契約〉
Pkcs11Signer::signPqs()string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = true除非已設定 $enablePostQuantum,否則拒絕;派送暫定的 PKCS#11 後量子機制string 原始簽章位元組HsmOperationException(已停用、token 失敗、簽章長度不符);InvalidArgumentException(context 超過 255 位元組)預覽;不做符合性聲明
Pkcs11Signer accessor surface唯讀的建構結果bool / string / array<string>isPostQuantumEnabled, getCertificateDer, getCertificateChainDer, getPublicKeyAlgorithm
OpenSslCliSigner::__construct()string $keyUri, string $certPath, string $pin, array $extraCertPaths = [], OpenSslCliBackend $backend = OpenSslCliBackend::Auto, string $opensslBinary = 'openssl', int $timeoutSeconds = 30, ?string $modulePath = null, ?string $configPath = null, bool $legacyPinDelivery = false, ?FipsSignatureEnforcer $fipsEnforcer = null驗證 proc_open、探測二進位檔、解析後端、載入憑證HsmOperationExceptionproc_open 已停用、缺少 module/config/憑證檔、無後端);InvalidArgumentException$keyUri 內含 pin-valueAuto 優先使用 OpenSSL 3.x provider,其次為 engine
OpenSslCliSigner::sign()string $data, string $algorithm = 'sha256WithRSAEncryption'在一個 openssl 子程序中簽署;PIN 預設透過一個短暫的 0600 pin-source 檔傳遞string 原始簽章位元組HsmOperationException(逾時、PIN 被拒、找不到金鑰、空白輸出);InvalidArgumentException(未對應的演算法);於簽署前的 FIPS 閘門例外子程序於 $timeoutSeconds 後被終止;stderr 會被遮蔽
OpenSslCliSigner accessor surface唯讀的建構結果string / array<string> / OpenSslCliBackendgetCertificateDer, getCertificateChainDer, getPublicKeyAlgorithm, getCertificatePem, getResolvedBackend, getOpensslVersion
OpenSslCliBackend列舉:ProviderEngineAutoCLI 簽署器的後端選擇
Pkcs11PqsAlgorithmML-DSA 與 SLH-DSA 參數集的列舉輔助方法:isMlDsa, isSlhDsa, mechanismId, parameterSetId, signatureLength, nistCategory
PqsCapabilityStatus::current()為程序建立誠實的後量子態勢PqsCapabilityStatus每個符合性聲明布林值都硬編碼為 false;沒有任何旗標能將其開啟
HsmSignerProviderAdapterHsmSignerInterface $hsm, string $providerId, SignatureAlgorithm $algorithm = SignatureAlgorithm::Pkcs1v15將一個 HSM 具體實作公開為統一的 SignerProviderInterface依 SPIKeyManagementException(非 null 的金鑰版本);SignatureFailedException(驅動程式失敗、空白簽章)Provider id:pkcs11-{module-id}, openssl-cli
HsmOperationException每條 HSM 簽署路徑的具型別失敗繼承 Core 的 NextPdfException
FipsCryptoPolicy::strict() / ::standard()?FipsSelfTest $selfTest = null工廠預設;strict 是 FIPS 140-3 設定檔,standard 另加 AES-128-CBCFipsCryptoPolicy不可變的允許清單;見 FIPS 模式行為
FipsCryptoPolicy predicate surfacestring / int 輸入允許清單成員檢查bool / stringisHashAlgorithmAllowed, isSignatureAlgorithmAllowed, isEncryptionAlgorithmAllowed, isKeyStrengthAllowed, getPreferredHashAlgorithm, getName
FipsCryptoPolicy::assertPreOperational()執行(或重播)開機自我測試voidFipsModuleErrorStateException由 Core 的強制執行接縫在第一次密碼學操作時驅動
FipsModeGuard::__construct()CryptoPolicyInterface $policy, ?FipsBootGuard $bootGuard = null, ?FipsAuditLogger $auditLogger = null以斷言式邊界包覆一個原則沒有 boot guard 時,自我測試閘門不存在(僅原則)
FipsModeGuard assert surfacestring / int 輸入先查拒絕目錄,再查允許清單;在任何拋出之前先記錄稽核voidFipsViolationExceptionFipsModuleErrorStateException(已接上 boot guard)assertHashAllowed, assertSignatureAlgorithmAllowed, assertEncryptionAllowed, assertKeyStrengthAllowed,外加 getPolicy
FipsBootGuard::report() / ::rerun()執行自我測試電池(快取 / 強制)FipsSelfTestReport一份 ERROR 報告會鎖存整個程序;一次通過的重跑絕不清除此鎖存
FipsBootGuard::assertOperational()斷言模組處於 OPERATIONALvoidFipsModuleErrorStateException黏性:程序層級鎖存的 ERROR 即使對一個乾淨的實例也會拒絕
FipsBootGuard::status()回報快取的狀態FipsSelfTestStatusPRE_OPERATIONAL, OPERATIONAL, or ERROR
FipsSelfTest::run()執行完整的已知答案測試(known-answer-test)電池;絕不短路FipsSelfTestReport建構子接受可注入的雜湊與隨機位元組供應者,以進行確定性測試
FipsSelfTestReport / FipsSelfTestResult / FipsSelfTestStatus報告值物件與狀態列舉FipsSelfTestReport::assertOperational() 拋出 FipsModuleErrorStateExceptionresults 始終列出每個結果作為稽核證據
FipsSignatureEnforcer::assertSignatureGenerationAllowed()string $algorithm, string $certificatePem解析簽章 OID 與金鑰強度,然後委派給守衛voidFipsViolationException(不被允許或無法分類,fail-closed)在 FIPS 模式下,兩個簽署器都在 sign() 開頭呼叫的節流點
FipsAuditLoggerCryptoPolicyInterface $policy, LoggerInterface $logger每個決策發出 ALLOW(INFO)/ DENY(WARNING)記錄每次記錄呼叫回傳 boollogHashOperation, logSignatureOperation, logEncryptionOperation, logKeyStrengthCheck
FipsTransitioningAlgorithmsstring / int 輸入靜態的 NIST SP 800-131A 拒絕目錄bool / array每個守衛邊界之下的明確拒絕層
FipsBootstrap::boot() / ::lazy()?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null, ?LoggerInterface $auditLogger = null組合 boot guard、原則與 mode guard;boot() 立即執行自我測試,lazy() 將其延後至第一個邊界FipsModeGuardboot():測試失敗時拋出 FipsModuleErrorStateException預設為 strict 原則
FipsBootstrap::signatureEnforcer()?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null啟動模組並回傳給簽署器使用的產生時閘門FipsSignatureEnforcerFipsModuleErrorStateException將結果傳入簽署器的 $fipsEnforcer 參數
FipsBootstrap::selfTestReport()?FipsSelfTest $selfTest = null隨選執行電池並加以摘要array{status, operational, failed}供健康檢查端點與 CLI 子指令使用
FipsViolationException / FipsModuleErrorStateException具型別的 FIPS 失敗分別公開 policyName / violatingItem / reasonfailedResults
public function __construct(private readonly string $libraryPath, private readonly int $slotId, #[SensitiveParameter] private readonly string $pin, #[SensitiveParameter] private readonly string $certLabel, #[SensitiveParameter] private readonly ?string $keyLabel = null, array $chainDer = [], private readonly bool $enablePostQuantum = false, ?FipsSignatureEnforcer $fipsEnforcer = null)
public static function isAvailable(): bool
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): string
public function signPqs(string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = true): string
public function __construct(private string $keyUri, string $certPath, #[SensitiveParameter] private string $pin, array $extraCertPaths = [], private OpenSslCliBackend $backend = OpenSslCliBackend::Auto, private string $opensslBinary = 'openssl', private int $timeoutSeconds = 30, private ?string $modulePath = null, private ?string $configPath = null, private bool $legacyPinDelivery = false, private ?FipsSignatureEnforcer $fipsEnforcer = null)
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): string
public static function strict(?FipsSelfTest $selfTest = null): self
public static function standard(?FipsSelfTest $selfTest = null): self
public function assertPreOperational(): void
public function __construct(private CryptoPolicyInterface $policy, private ?FipsBootGuard $bootGuard = null, private ?FipsAuditLogger $auditLogger = null)
public function assertHashAllowed(string $algorithm): void
public function assertSignatureAlgorithmAllowed(string $oid): void
public function assertEncryptionAllowed(string $algorithm): void
public function assertKeyStrengthAllowed(string $keyType, int $bitLength): void
public function getPolicy(): CryptoPolicyInterface
public static function boot(?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null, ?LoggerInterface $auditLogger = null): FipsModeGuard
public static function lazy(?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null, ?LoggerInterface $auditLogger = null): FipsModeGuard
public static function signatureEnforcer(?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null): FipsSignatureEnforcer
public static function selfTestReport(?FipsSelfTest $selfTest = null): array
  • 合約解析。 兩個簽署器都實作 Core 的 HsmSignerInterface;該原則實作 Core 的 CryptoPolicyInterface。呼叫端程式碼依賴合約,因此版本升級改變的是組合,而非呼叫點。
  • 金鑰保管。 私鑰絕不離開 token 邊界。Pkcs11Signer 將操作委派給 token;OpenSslCliSigner 將一個 PKCS#11 URI 金鑰參照傳給子程序。NextPDF 不儲存、不產生,也不保證簽署金鑰的安全。金鑰保護是操作者的保管責任(NIST SP 800-57 Part 1 Rev.5 §5.5.2)。
  • 工作階段與登入。 token 簽署操作、工作階段與使用者登入遵循 PKCS#11 v3.1 §5。憑證標籤與私鑰標籤可以不同;建構子為此類 token 接受一個獨立的金鑰標籤。
  • 封閉演算法集合。 簽署器恰好接受:搭配 SHA-256/384/512 的 RSA PKCS#1 v1.5、搭配 SHA-256/384/512 的 RSASSA-PSS,以及搭配 SHA-256/384/512 的 ECDSA(Pkcs11Signer 亦接受 ecdsa-raw)。任何其他識別碼都會引發 InvalidArgumentException;絕不簽署任何替代演算法。
  • PSS salt 綁定。 對於每個 PSS 變體,salt 長度等於摘要長度——32、48 或 64 位元組——且雜湊與遮罩產生參數與所選摘要一致(PKCS#11 v3.1 §5)。
  • ECDSA 轉換。 token ECDSA 機制回傳原始簽章;sign() 會將其轉換為 DER 編碼的 ECDSA-Sig-Value 形式,以利 PDF 與 OpenSSL 互通。簽章產生遵循 FIPS 186-5 §6.3.2。
  • 預設內容。 strict 預設允許 SHA-256/384/512;搭配那些雜湊的 RSA 與 ECDSA 簽章 OID;RSASSA-PSS;AES-256-CBC 與 AES-256-GCM;最小 RSA 2048 與 EC 256。standard 預設另外允許 AES-128-CBC 以利舊式互通。任何 AES-GCM 使用都要求每把金鑰有一個唯一的初始化向量(NIST SP 800-38D §5)。
  • 雙層強制。 每個守衛邊界先查詢明確的 NIST SP 800-131A 拒絕目錄,再查詢原則允許清單。拒絕層產生稽核清晰的「不被允許」訊號;允許清單仍為權威。
  • 開機自我測試。 該電池涵蓋 SHA-256/384/512、HMAC-SHA-256、AES-256-CBC、AES-256-GCM、一個 ECDSA P-256 成對一致性測試,以及一個隨機位元健康檢查。在 Core 路徑上,原則之下的第一次密碼學操作會於每個程序執行它一次,fail-closed。失敗會讓模組進入 ERROR 狀態;在重設之前拒絕提供密碼學服務。此遵循 ISO/IEC 19790:2025 §7.10、§7.10.2、§7.10.3 與 §7.10.3.p3。
  • 黏性 ERROR 狀態。 一個被觀察到的 ERROR 會鎖存整個程序。建構一個全新的原則或 boot guard 無法將其洗清;一次通過的重跑不會清除它。只有程序重啟——一次真正的電源循環——才會重設此狀態。
  • 僅限產生閘門。 FipsSignatureEnforcer 管轄產生新簽章。對既有簽章的驗證屬於舊式使用,絕不經由 enforcer。
  • 稽核軌跡。 當守衛與稽核記錄器組合時,每個邊界在允許或拒絕操作之前都會發出一筆 ALLOW 或 DENY 記錄。記錄器查詢守衛所強制的同一個原則,因此記錄的決策不會分歧。
  • 在沒有 ext-pkcs11 的情況下建構 Pkcs11Signer 會立即引發 HsmOperationException;標準 PHP 發行版並未隨附此擴充。
  • 未對應任何 token 物件的憑證或私鑰標籤會引發 HsmOperationException,並指名缺少的物件類別。
  • OpenSslCliSigner 在建構時拒絕含有 pin-value$keyUri,fail-closed;PIN 改為透過安全的 pin-source 路徑傳遞。
  • 在 FIPS 模式下,無法對應到已知簽章 OID 的演算法識別碼會被 fail-closed 拒絕;公鑰強度無法確定的憑證亦然。
  • 未知的金鑰型別預設被拒絕;原則絕不退回到較弱的演算法。
  • 失敗的已知答案測試會引發 FipsModuleErrorStateException,其中攜帶失敗結果;程序中之後的每個邊界都會重複此失敗,直到重啟為止。
  • 沒有 boot guard 而建構的守衛會強制允許清單,但不提供自我測試閘門;正式的 FIPS 組合會透過 bootstrap 提供一個。
  • 除非設定了建構子的選用啟用,否則 signPqs() 拒絕執行。超過 255 位元組的 context 字串會引發 InvalidArgumentException(FIPS 204 §5.4)。回傳簽章的位元組長度若與所選參數集不符,會在其到達編碼之前被拒絕。

strict 模式中 FIPS 允許:SHA-256/384/512;搭配那些雜湊的 RSA PKCS#1 v1.5 與 RSA-PSS;搭配那些雜湊的 ECDSA;AES-256-CBC 與 AES-256-GCM;RSA 至少 2048 位元、EC 至少 256 位元。strict 模式中 FIPS 拒絕:較弱或舊式的雜湊、非核准的簽章 OID、AES-128(僅在 standard 預設中允許),以及任何低於最小強度的金鑰。最小 RSA 金鑰長度與轉換狀態遵循 NIST SP 800-131A Rev.2 §3。ECDSA 曲線與雜湊配對遵循 FIPS 186-5 §6.1.1。此路徑為 fail-closed,且絕不以較弱的演算法替代。

NextPDF Enterprise 不是經 FIPS 驗證的密碼學模組,亦不做任何 FIPS 認證聲明。 NextPDF Enterprise 只有在被設定為搭配一個經 FIPS 驗證的密碼學供應者——例如一個經 FIPS 驗證的 OpenSSL 供應者——或一個經 FIPS 驗證的 HSM 時,才以 FIPS 相容模式運作。FIPS 模式原則協助合規;它不是認證。本儲存庫中不存在任何 FIPS 認證成品。

聲明標準條款
token 簽署操作、工作階段與使用者登入語意PKCS#11 v3.1§5 (sign)
PSS salt 長度等於摘要長度PKCS#11 v3.1§5 (PSS sLen)
ECDSA 簽章產生;曲線與雜湊配對FIPS 186-5§6.3.2; §6.1.1
最小 RSA 金鑰長度與簽章產生轉換狀態NIST SP 800-131A Rev.2§3
自我測試類別、文件、條件式觸發、不相交集合ISO/IEC 19790:2025§7.10, §7.10.2, §7.10.3, §7.10.3.p3
AES-GCM 初始化向量唯一性NIST SP 800-38D§5
金鑰保護與保管責任NIST SP 800-57 Part 1 Rev.5§5.5.2
後量子簽署 context 字串限制為 255 位元組FIPS 204§5.4

所有條款皆為改寫;未重現任何規範性文字。這些是關於 NextPDF 程式碼的能力聲明,而非認證。所產生的簽章是否通過驗證,是驗證者依其自身信任設定所做的決定。FIPS 模式原則是一項合規協助功能,不是法律意見;請諮詢你自己的合規與法律顧問。本模組涉及密碼學功能;請在你自己的審查中將其視為安全敏感。

  • 透過 bootstrap 組合 FIPS 模式:boot() 提供啟動時閘門,lazy() 將電池延後至第一個邊界,以及 enforcer 工廠供簽署器的 $fipsEnforcer 參數使用。非 FIPS 部署傳入 null,行為不變。
  • bin/nextpdf-enterprisefips:self-test 子指令隨選執行電池,並在 ERROR 狀態下以非零值退出;請將其接到維護工作或僅限管理員的健康檢查端點(ISO/IEC 19790:2025 隨選自我測試)。
  • FipsBootGuard::resetProcessErrorLatchForTesting()@internal 且僅供測試;正式程式碼絕不呼叫它,因為那會破壞黏性 ERROR 狀態。
  • 簽署器建構一次即重複使用;建構過程會登入並讀取憑證,而每函式庫的模組快取使得對同一函式庫的重複建構是安全的。
  • 從機密管理器提供 PIN。它是 #[SensitiveParameter],絕不記錄或序列化;請勿將其提交至設定中。
  • 操作者負責 token 配置、PIN 處理、slot 設定、網路型 HSM 的網路保護,以及信任設定。本頁不揭露 token PIN 原則內部實作或廠商憑證材料。
  • 請勿為正式的 AdES 簽章啟用後量子預覽。AdES 密碼學套件目錄尚未承認後量子套件,多數 PDF 檢視器會拒絕此類簽章,且硬體往返驗證尚未完成。內部機制細節保留在來源儲存庫的內部文件中,不在本手冊範圍內。

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