跳到內容

簽章驗證:AdES / PAdES 密碼學驗證端

NextPDF Enterprise 以密碼學方式驗證數位簽章。驗證端會從 PDF 讀取 CMS SignedData 或 RFC 3161 時間戳記權杖,重新計算摘要、檢查簽章、將每個簽章繫結至其簽署憑證,並針對呼叫端提供的信任錨點儲存區驗證憑證鏈——包含憑證原則處理。本頁以行為層級說明哪些項目會被驗證、哪些會以 fail-closed 方式拒絕、支援哪些演算法,以及信任邊界落在何處。

這與 Validation 不同;後者執行唯讀的結構性原則檢查,並刻意不執行任何密碼學運算。它也是 簽章產生器的驗證端對應元件;後者會寫入 PAdES B-LT / B-LTA 結構。

Terminal window
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_policyinhibit_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 下通過驗證的基本簽章會被降級為密碼學約束失敗,而非通過

驗證端透過公開引擎以及 Core / Pki 契約使用。具體策略類別供內部使用。

型別種類角色
AdESValidationEngineclass驗證端進入點:簽章與封存鏈驗證。
AdESValidationEngine::validateArchivalTimestampChain()method驗證一條涵蓋 PDF 位元組範圍、受信任的 DocTimeStamp 涵蓋鏈。
ValidationReportresult結構化的結果:整體狀態加上逐項檢查的發現。
PathValidatorInterfaceinterface(NextPDF\…\Pki引擎所依賴的憑證路徑驗證 SPI。
PathValidationOptionsvalue object原則處理控制項:requireExplicitPolicyinhibitAnyPolicyinhibitPolicyMappingmaxPolicyFanout
TrustAnchorStoreInterfaceinterface由呼叫端提供、用以評估憑證鏈的受信任錨點集合。

封存鏈方法的簽章如下:

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 歸零且有效原則樹為空的憑證鏈現在會失敗——包含由鏈內 policyConstraints requireExplicitPolicy 所驅動的情況。預設、不受約束的憑證鏈(無必要原則、接受 anyPolicy)不受影響。
  • 建構函式簽名變更(BC break)。 AdESValidationEngine::__construct() 現在將其 $chainValidator 參數的型別宣告為 Pki\PathValidatorInterface SPI,並延遲預設為 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 讀取器剖析;該讀取器會拒絕格式錯誤或不定長的編碼。

驗證在處理程序內、於本機進行,無任何網路 I/O。憑證與簽章帶有主體身分;請對報告及任何擷取的憑證資料套用你自己的保留與最小化控制。

發現項目帶有檢查識別碼與狀態。某些診斷可能會回顯憑證主體名稱或序號;在將日誌轉送至共用接收端之前,請清理或遮蔽這些欄位。

請在使用者可見的輸出中陳述這些界限,以免正面結果被過度解讀。

  • validateArchivalTimestampChain() 證明的是位元組範圍涵蓋,而非 xref 可達性。 它確立的是:一條受信任的時間戳記鏈以密碼學方式涵蓋文件的位元組範圍直到 EOF。它不執行 xref 層級或 startxref 物件可達性分析;那是刻意排除於範圍之外的。附加於時間戳記之後的攻擊,是由 EOF 涵蓋規則搭配信任錨定所抵擋,而非由物件圖分析。
  • 刻意排除於範圍之外。 此驗證端不提供 Evidence Records(RFC 4998 / RFC 6283);不提供 RSASSA-PSS、EdDSA 或 SHA-3 時間戳記權杖的驗證;不提供受信任清單(TSL)與合格 TSA 整合;亦不提供線上 TSA 撤銷擷取。撤銷是依驗證器可取得的材料評估。
行為參考狀態
簽章值/時間戳記權杖以 DER 編碼儲存於 /ContentsISO 32000-2 §12.8.1已剖析並驗證
文件時間戳記字典ISO 32000-2 §12.8.5為封存鏈讀取
接收端重新計算內容摘要;其必須等於 messageDigest 屬性RFC 5652 §5.6 / §5.4已強制執行
TSA 憑證帶有單一關鍵的 id-kp-timeStamping EKURFC 3161 §2.3於 genTime 檢查
genTime 為 UTC 建立時刻RFC 3161 §2.4.2作為驗證時間使用
原則處理狀態變數(explicit_policyinhibit_anyPolicyRFC 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 認證聲明。 此驗證端實作引用規格所描述的密碼學檢查;它並非經認證的驗證服務,亦不產生任何第三方證明。

當 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-timeStamping EKU、有效期間、具信任錨點的憑證鏈,以及撤銷。
  • 一個 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 會被降級。

此公開頁面僅描述外部可觀察的驗證端行為。它透過受支援的介面明列公開引擎、Pki / 信任錨點契約,以及 validateArchivalTimestampChain() 方法。具體的 DER、CMS、原則處理器與路徑驗證器內部,位於 NDA 下的閘控深度參考中。

NextPDF Core 偵測簽章是否存在並產生 B-B / B-T 簽章,但它不以密碼學方式驗證 CMS 或時間戳記權杖、不驗證封存鏈,亦不執行 RFC 5280 §6.1.4 原則處理。僅部署 Core 的環境沒有對等的驗證端;請參閱 Security / Signing (Core)

NextPDF Pro 新增簽署策略與電子發票處理,但不提供此密碼學驗證端;封存鏈驗證與憑證原則處理僅在 nextpdf/enterprise 中提供。

此驗證端以行為層級描述。嚴格 DER 堆疊、CMS 剖析器、原則處理器與路徑驗證器內部,超出公開介面範圍,且不在此重製。

驗證取決於信任錨點儲存區,以及呼叫端提供或文件中內嵌的任何撤銷材料。NextPDF Enterprise 會評估該材料;它不營運信任清單、TSA 或撤銷服務。操作者負責錨點選擇與內嵌撤銷材料的新鮮度。

此頁面標記為 export_control_class: legal-review-required;它涉及密碼學驗證。在設定 publish 旗標之前,須取得法務簽核。正面的驗證結果是關於文件簽章與時間戳記的密碼學陳述——它不是法律意見、不是 eIDAS 合格性判定,也不是認證。NextPDF 不作任何 AdES / PAdES 認證聲明。 關於你的法規義務,請洽詢你自己的合規與法律顧問。