簽章驗證:AdES / PAdES 密碼學驗證端
快速總覽
標題為「快速總覽」的區段NextPDF Enterprise 以密碼學方式驗證數位簽章。驗證端會從 PDF 讀取 CMS SignedData 或 RFC 3161 時間戳記權杖,重新計算摘要、檢查簽章、將每個簽章繫結至其簽署憑證,並針對呼叫端提供的信任錨點儲存區驗證憑證鏈——包含憑證原則處理。本頁以行為層級說明哪些項目會被驗證、哪些會以 fail-closed 方式拒絕、支援哪些演算法,以及信任邊界落在何處。
這與 Validation 不同;後者執行唯讀的結構性原則檢查,並刻意不執行任何密碼學運算。它也是 簽章產生器的驗證端對應元件;後者會寫入 PAdES B-LT / B-LTA 結構。
composer require nextpdf/enterprise:^3概念總覽
標題為「概念總覽」的區段驗證以證據為本,並採 fail-closed:無法正面確認的檢查不會產生正面結果。下列各部分會組成由 ValidationReport 承載的結果。
CMS / 時間戳記權杖的密碼學驗證。 自包含、嚴格且採定長的 DER 堆疊會剖析 CMS SignedData 與 RFC 3161 時間戳記權杖。唯有當權杖恰好帶有一個 SignerInfo、其簽署屬性通過嚴格剖析、簽署者憑證可解析、message-digest 屬性與重新計算的摘要相符、必要的簽署憑證(ESS signing-certificate-v2)繫結成立,且 SignerInfo 簽章能以重新加標籤的簽署屬性通過驗證時,權杖才會被接受。摘要比對規則即 RFC 5652 §5.6 / §5.4 的驗證模型:接收端重新計算內容訊息摘要;唯有當該值等於 messageDigest 簽署屬性時,簽章才有效——驗證者絕不信任由產生器提供的摘要。
在 genTime 進行的 TSA 憑證驗證。 時間戳記的 genTime 是該權杖建立時的 UTC 時刻(RFC 3161 §2.4.2)。TSA 簽署憑證是在那個時刻而非「現在」進行驗證:其延伸金鑰用途必須是單一、關鍵的 id-kp-timeStamping(RFC 3161 §2.3),且其有效期間、憑證鏈、信任錨點來源與撤銷皆會針對 genTime 評估。即使憑證鏈在結構上格式正確,只要無法連到已設定的信任錨點,永遠無法支撐正面結果。
分離式 PAdES 基本文件簽章。 專用擷取器會對分離式文件簽章執行真正的 AdES / PAdES 基本驗證:對已簽署的位元組範圍重新計算訊息摘要並比對、驗證簽章,且簽署憑證繫結為必要項。這取代了先前僅做結構性檢查的回退機制。時間戳記驗證器與文件簽章擷取器共用同一個 ESS issuer-and-serial 驗證器,因此兩者在憑證繫結剖析上不會出現不一致。
封存 DocTimeStamp 涵蓋鏈。 validateArchivalTimestampChain() 會驗證一條由受信任 DocTimeStamp 權杖構成、涵蓋 PDF 位元組範圍的鏈,作為 B-LTA 封存證據。每個權杖的印記都繫結至其實際涵蓋的 ByteRange 位元組;該鏈遵循嚴格的 ETSI 排序,每個權杖的 TSA 鏈皆有信任錨點,且該鏈必須涵蓋檔案直到檔案結尾標記。唯有完整、具信任錨點且涵蓋至 EOF 的鏈,才能取得完全通過的結果。
憑證原則處理(RFC 5280 §6.1.4)。 路徑驗證會套用完整的憑證原則處理:以節點表示的原則樹、帶有 anyPolicy 回退的原則對映,以及 policyConstraints / inhibitAnyPolicy 折疊,並由 fail-closed 的原則延伸 DER 讀取器支撐。路徑處理的狀態變數 explicit_policy 與 inhibit_anyPolicy(RFC 5280 §6.1.2)決定是否要求非空的有效原則樹;收尾步驟會將有效原則樹與 user-initial-policy-set 取交集(RFC 5280 §6.1.4)。在無必要原則且接受 anyPolicy 的情況下,處理不受約束——這是預設值,且與先前行為相同。
支援的演算法
標題為「支援的演算法」的區段驗證端接受下列演算法集合,並對集合之外的任何項目以 fail-closed 方式拒絕:不支援的演算法即代表驗證遭拒,絕不會靜默通過。
| 系列 | 支援 | 備註 |
|---|---|---|
| RSA(PKCS#1 v1.5) | rsaEncryption 搭配 SHA-2,以及 sha*WithRSAEncryption OID | 接受 |
| ECDSA | 曲線 P-256、P-384、P-521 | 接受 |
| RSASSA-PSS | — | 不支援 → fail-closed |
| EdDSA | — | 不支援 → fail-closed |
| SHA-3 摘要 | — | 不支援 → fail-closed |
| SHA-1 | — | 弱:在 SHA-1 下通過驗證的基本簽章會被降級為密碼學約束失敗,而非通過 |
API 介面
標題為「API 介面」的區段驗證端透過公開引擎以及 Core / Pki 契約使用。具體策略類別供內部使用。
| 型別 | 種類 | 角色 |
|---|---|---|
AdESValidationEngine | class | 驗證端進入點:簽章與封存鏈驗證。 |
AdESValidationEngine::validateArchivalTimestampChain() | method | 驗證一條涵蓋 PDF 位元組範圍、受信任的 DocTimeStamp 涵蓋鏈。 |
ValidationReport | result | 結構化的結果:整體狀態加上逐項檢查的發現。 |
PathValidatorInterface | interface(NextPDF\…\Pki) | 引擎所依賴的憑證路徑驗證 SPI。 |
PathValidationOptions | value object | 原則處理控制項:requireExplicitPolicy、inhibitAnyPolicy、inhibitPolicyMapping、maxPolicyFanout。 |
TrustAnchorStoreInterface | interface | 由呼叫端提供、用以評估憑證鏈的受信任錨點集合。 |
封存鏈方法的簽章如下:
public function validateArchivalTimestampChain( string $pdfBytes, array $dssData = [], ?TrustAnchorStoreInterface $anchors = null,): ValidationReport;唯有當 DocTimeStamp 鏈完整通過驗證、具信任錨點,且涵蓋檔案直到其 EOF 標記時,才會達到完全通過的結果。
CertificateChainValidator::validate() 接受一組初始原則集合(即 RFC 5280 的 user-initial-policy-set)。預設為 anyPolicy——不受約束——因此一般憑證鏈不受影響;若需要非空的有效原則樹,請傳入明確的集合,或設定 requireExplicitPolicy。
程式碼範例——快速上手
標題為「程式碼範例——快速上手」的區段use NextPDF\Enterprise\Security\Validation\AdESValidationEngine;
$report = $engine->validateArchivalTimestampChain($pdfBytes, [], $trustAnchors);
if ($report->isTotalPassed()) { // A complete, trust-anchored, EOF-covering DocTimeStamp chain.}程式碼範例——正式環境
標題為「程式碼範例——正式環境」的區段use NextPDF\Enterprise\Security\Validation\AdESValidationEngine;use Psr\Log\LoggerInterface;
final readonly class ArchivalEvidenceCheck{ public function __construct( private AdESValidationEngine $engine, private LoggerInterface $logger, ) {}
public function check(string $pdfBytes, TrustAnchorStoreInterface $anchors): bool { $report = $this->engine->validateArchivalTimestampChain($pdfBytes, [], $anchors);
foreach ($report->findings as $finding) { $this->logger->info('archival.finding', [ 'check' => $finding->checkId, 'status' => $finding->status->value, ]); }
// A positive result proves byte-range coverage by a trusted timestamp // chain — it is one input to your decision, not a legal conclusion. return $report->isTotalPassed(); }}行為變更與升級注意事項
標題為「行為變更與升級注意事項」的區段驗證端已從結構性/時間性接受轉為完整的密碼學驗證。任何依賴舊有較寬鬆行為的使用者,都應檢視這些變更。
- 對可辨識但無法驗證的時間戳記採取 fail-closed。 先前以結構性與時間性理由通過的 DocTimeStamp 或封存權杖,現在需要完整的密碼學驗證——簽章、message-digest 以及簽署憑證繫結。無法通過驗證的權杖不再產生正面的存在證明;它會對應為不確定或失敗的結果。
- SHA-1 基本簽章會被降級,而非通過。 通過驗證但使用 SHA-1 的基本文件簽章,會被回報為密碼學約束失敗,而非完全通過。
- RFC 5280 §6.1.4 憑證原則處理會被強制執行。 一條
explicit_policy歸零且有效原則樹為空的憑證鏈現在會失敗——包含由鏈內policyConstraintsrequireExplicitPolicy所驅動的情況。預設、不受約束的憑證鏈(無必要原則、接受anyPolicy)不受影響。 - 建構函式簽名變更(BC break)。
AdESValidationEngine::__construct()現在將其$chainValidator參數的型別宣告為Pki\PathValidatorInterfaceSPI,並延遲預設為Pki\CertificateChainValidator::withDefaults()。它先前是具體的Ltv\CertificateChainValidator。先前注入具體 LTV 驗證器的呼叫端,必須改為注入 Pki SPI 實作。Pki 驗證器包覆同一個結構性路徑引擎,並加上名稱約束與原則處理;對符合規範的預設輸入而言,它是無操作(no-op)。
邊界情況與陷阱
標題為「邊界情況與陷阱」的區段- 不支援的演算法 ≠ 無法定論。 RSASSA-PSS、EdDSA 與 SHA-3 會被 fail-closed 拒絕,而非延後處理。若你的簽署者使用這些演算法,此驗證端不會為其回傳正面結果。
- 信任是相對於錨點的。 驗證永遠相對於你所提供的信任錨點儲存區。空的或錯誤的錨點集合會產生不受信任的結果,無論密碼學是否正確。
- genTime,而非現在。 TSA 憑證是在權杖的
genTime進行判定。一個其後已過期的 TSA 憑證,仍可支撐其有效期間內所建立的權杖;而在genTime時尚未生效的憑證則不能。 - EOF 涵蓋。 封存鏈必須涵蓋文件直到其 EOF 標記。只涵蓋檔案前綴部分的時間戳記,無法確立整份文件的涵蓋。
- 未被證明已撤銷不等於良好(Good)。
Valid判定需要確切未撤銷的狀態。若 OCSP 與 CRL 都回傳 Unknown 或 Unavailable,即使是密碼學上正確、鏈有效且具信任錨點的簽章,也會判定為Indeterminate——請為簽署者憑證提供內嵌的 OCSP/CRL Good 材料,才能達到Valid。
驗證是在處理程序內,針對所提供的 PDF 位元組與內嵌驗證材料進行;成本會隨鏈長度與時間戳記數量而擴增。驗證期間不進行任何網路往返——撤銷與信任材料皆取自呼叫端所提供或文件中內嵌的內容。驗證具決定性:相同的輸入與相同的信任錨點會產生相同的報告。
安全性注意事項
標題為「安全性注意事項」的區段- fail-closed 是預設。 每個接受步驟都拒絕接受無法正面驗證的材料。這可防止文件主張引擎從未確立的有效性。
- 附加於時間戳記之後的內容會被 EOF 涵蓋規則擋下。 由於每個封存時間戳記的印記都繫結至實際的
ByteRange位元組,且該鏈必須抵達 EOF,因此在時間戳記之後附加的內容不會被它涵蓋,也不會取得其證據效力。 - 將輸入視為惡意。 來自不受信任來源的 PDF 位元組、內嵌 CMS 與時間戳記權杖,皆由嚴格的定長 DER 讀取器剖析;該讀取器會拒絕格式錯誤或不定長的編碼。
資料落地與 PII 緩解
標題為「資料落地與 PII 緩解」的區段驗證在處理程序內、於本機進行,無任何網路 I/O。憑證與簽章帶有主體身分;請對報告及任何擷取的憑證資料套用你自己的保留與最小化控制。
安全的遙測與日誌清理
標題為「安全的遙測與日誌清理」的區段發現項目帶有檢查識別碼與狀態。某些診斷可能會回顯憑證主體名稱或序號;在將日誌轉送至共用接收端之前,請清理或遮蔽這些欄位。
範圍界限
標題為「範圍界限」的區段請在使用者可見的輸出中陳述這些界限,以免正面結果被過度解讀。
validateArchivalTimestampChain()證明的是位元組範圍涵蓋,而非 xref 可達性。 它確立的是:一條受信任的時間戳記鏈以密碼學方式涵蓋文件的位元組範圍直到 EOF。它不執行 xref 層級或startxref物件可達性分析;那是刻意排除於範圍之外的。附加於時間戳記之後的攻擊,是由 EOF 涵蓋規則搭配信任錨定所抵擋,而非由物件圖分析。- 刻意排除於範圍之外。 此驗證端不提供 Evidence Records(RFC 4998 / RFC 6283);不提供 RSASSA-PSS、EdDSA 或 SHA-3 時間戳記權杖的驗證;不提供受信任清單(TSL)與合格 TSA 整合;亦不提供線上 TSA 撤銷擷取。撤銷是依驗證器可取得的材料評估。
一致性
標題為「一致性」的區段| 行為 | 參考 | 狀態 |
|---|---|---|
簽章值/時間戳記權杖以 DER 編碼儲存於 /Contents | ISO 32000-2 §12.8.1 | 已剖析並驗證 |
| 文件時間戳記字典 | ISO 32000-2 §12.8.5 | 為封存鏈讀取 |
| 接收端重新計算內容摘要;其必須等於 messageDigest 屬性 | RFC 5652 §5.6 / §5.4 | 已強制執行 |
TSA 憑證帶有單一關鍵的 id-kp-timeStamping EKU | RFC 3161 §2.3 | 於 genTime 檢查 |
| genTime 為 UTC 建立時刻 | RFC 3161 §2.4.2 | 作為驗證時間使用 |
原則處理狀態變數(explicit_policy、inhibit_anyPolicy) | RFC 5280 §6.1.2 | 已處理 |
| 收尾步驟將有效原則樹與 user-initial-policy-set 取交集 | RFC 5280 §6.1.4 | 已強制執行 |
| 針對長期簽章的 DSS 項目與文件時間戳記 | ETSI EN 319 142-2 §5.5 | 已驗證為封存證據 |
所有條款皆為意譯。NextPDF 不重製規範性文字;如需具權威性的措辭,請查閱已發布的標準。NextPDF 不作任何 AdES / PAdES 認證聲明。 此驗證端實作引用規格所描述的密碼學檢查;它並非經認證的驗證服務,亦不產生任何第三方證明。
FIPS 模式行為
標題為「FIPS 模式行為」的區段當 Enterprise FIPS 設定檔啟用時,該約束會套用於驗證器所接受的摘要與簽章演算法。驗證邏輯——摘要重新計算、簽章檢查、憑證繫結與路徑驗證——維持不變。
威脅模型
標題為「威脅模型」的區段| 資產 | 對手 | 風險 | 緩解 |
|---|---|---|---|
| 時間戳記權杖 | 偽造或竄改的權杖 | 虛假的存在證明 | 完整的密碼學驗證;對任何無法驗證者採 fail-closed |
| TSA 憑證 | 不受信任的簽發者 | 驗證器不應主張的表面信任 | 憑證鏈於 genTime 驗證至呼叫端提供的錨點;不受信任的鏈永不通過 |
| 文件位元組 | 附加於時間戳記之後 | 內容在未被涵蓋的情況下取得時間戳記效力 | 印記繫結至實際 ByteRange 位元組 + EOF 涵蓋規則 |
| 弱演算法 | 降級為 SHA-1 / 不支援的方案 | 弱簽章被判讀為有效 | SHA-1 降級;RSASSA-PSS / EdDSA / SHA-3 fail-closed |
版本閘門
標題為「版本閘門」的區段此驗證端是 Enterprise 功能,隨 nextpdf/enterprise 套件提供。 NextPDF Core 偵測簽章是否存在並產生 B-B / B-T 簽章;它不提供此密碼學驗證端。 取得授權。
授權功能旗標
標題為「授權功能旗標」的區段此驗證端由 Enterprise 版本閘控(license_feature_flag: enterprise)。它透過 Core 與 Pki 契約解析;公開 API 不會因版本升級而改變。
行為契約
標題為「行為契約」的區段- 唯有具備恰好一個
SignerInfo、通過嚴格剖析的簽署屬性、已解析的簽署者憑證、相符的 message-digest、必要的簽署憑證繫結,以及通過驗證的SignerInfo簽章時,CMS 或時間戳記權杖才會被接受。 - TSA 憑證在權杖的
genTime進行驗證:單一關鍵的id-kp-timeStampingEKU、有效期間、具信任錨點的憑證鏈,以及撤銷。 - 一個
Valid判定還額外要求確切未撤銷的狀態——至少一個具權威性的 Good(一個經驗證為良好的 OCSP 回應,或一份有效期內且不包含該序號的最新 CRL)。一個僅是未被證明已撤銷、且 OCSP 與 CRL 皆為 Unknown 或 Unavailable 的狀態,會判定為Indeterminate,絕不會是Valid(ETSI EN 319 102-1:撤銷狀態無法取得 → INDETERMINATE)。由於 CRL 回退路徑僅證明清單的新鮮度,而非逐序號的撤銷狀態,因此一條僅有 CRL、缺少 Good OCSP 的鏈通常為Indeterminate。 validateArchivalTimestampChain()唯有針對完整、具信任錨點且涵蓋至 EOF 的 DocTimeStamp 鏈才會達到完全通過的結果;它證明的是位元組範圍涵蓋,而非 xref 可達性。- 憑證原則處理遵循 RFC 5280 §6.1.4;預設不受約束的憑證鏈不受影響。
- 支援的演算法為 RSA(PKCS#1 v1.5 搭配 SHA-2)與 ECDSA(P-256/384/521);RSASSA-PSS、EdDSA 與 SHA-3 採 fail-closed;SHA-1 會被降級。
NDA 掃描狀態
標題為「NDA 掃描狀態」的區段此公開頁面僅描述外部可觀察的驗證端行為。它透過受支援的介面明列公開引擎、Pki / 信任錨點契約,以及 validateArchivalTimestampChain() 方法。具體的 DER、CMS、原則處理器與路徑驗證器內部,位於 NDA 下的閘控深度參考中。
Core 回退
標題為「Core 回退」的區段NextPDF Core 偵測簽章是否存在並產生 B-B / B-T 簽章,但它不以密碼學方式驗證 CMS 或時間戳記權杖、不驗證封存鏈,亦不執行 RFC 5280 §6.1.4 原則處理。僅部署 Core 的環境沒有對等的驗證端;請參閱 Security / Signing (Core)。
Pro 回退
標題為「Pro 回退」的區段NextPDF Pro 新增簽署策略與電子發票處理,但不提供此密碼學驗證端;封存鏈驗證與憑證原則處理僅在 nextpdf/enterprise 中提供。
Enterprise 邊界說明
標題為「Enterprise 邊界說明」的區段此驗證端以行為層級描述。嚴格 DER 堆疊、CMS 剖析器、原則處理器與路徑驗證器內部,超出公開介面範圍,且不在此重製。
部署邊界
標題為「部署邊界」的區段驗證取決於信任錨點儲存區,以及呼叫端提供或文件中內嵌的任何撤銷材料。NextPDF Enterprise 會評估該材料;它不營運信任清單、TSA 或撤銷服務。操作者負責錨點選擇與內嵌撤銷材料的新鮮度。
法律合規邊界
標題為「法律合規邊界」的區段此頁面標記為 export_control_class: legal-review-required;它涉及密碼學驗證。在設定 publish 旗標之前,須取得法務簽核。正面的驗證結果是關於文件簽章與時間戳記的密碼學陳述——它不是法律意見、不是 eIDAS 合格性判定,也不是認證。NextPDF 不作任何 AdES / PAdES 認證聲明。 關於你的法規義務,請洽詢你自己的合規與法律顧問。
另請參閱
標題為「另請參閱」的區段- Signature:PAdES B-LT / B-LTA 產生器 —— 產生器端。
- Validation —— 處理程序內的結構性原則檢查(無密碼學)。
- Archive:DSS、VRI、LTV health —— 長期封存與 LTV 健康狀態。
- Security / Signing (Core) —— CMS、RFC 3161、RFC 5280 路徑驗證、OCSP/CRL。
- PAdES 基準對映 —— 跨版本的 B-B、B-T、B-LT、B-LTA。
- PAdES · DSS · LTV —— 詞彙表術語。