跳到內容
getnextpdf.com

Enterprise 版本

鑑識

NextPDF Enterprise Forensics 會讀取一份 PDF 的增量更新歷史,並產生一份結構化、唯讀的報告,內含各修訂版、已歸類的事件,以及每個物件的變更。它支援鑑識分析工作流程。它不是一個防竄改封緘,也不主張一份文件是真實或未經更動的。

此功能隨附於 NextPDF Enterprisenextpdf/enterprise),並透過一份 Enterprise 層級的授權封套啟用。一個沒有該權益的部署不會載入此功能的類別。比較版本並取得授權

Terminal window
composer require nextpdf/enterprise:^3

一份 PDF 可以透過將變更附加到檔案末尾來更新,而非重寫它。每一次更新會加入一個新的交叉參照區段與一個新的 trailer,而原始位元組會留在原處——ISO 32000-2:2020 §7.5.6。當一個物件被變更時,更新會附加一個新副本,而該更新的交叉參照區段會記錄一個覆寫舊偏移量的位元組偏移量;讀取器會解析最新的副本——ISO 32000-2:2020 §7.5.6。初始檔案結構可能被後續更新修改——ISO 32000-2:2020 §7.5.4。一次更新的交叉參照區段只列出在該次更新中被新增、修改或刪除的物件——ISO 32000-2:2020 §7.5.5。

分析器會讀取這個分層結構。它會剖析每個修訂版的交叉參照表、推導修訂版位元組邊界,並將每個修訂版的項目與次新的修訂版比對,以將每個物件歸類為新增、修改或刪除。接著它會將物件變更分組為更高層次的事件:加入了一個簽章、文件 catalog 被更新、出現了一個加密字典,或一組物件被新增、修改或移除。輸出是一個報告物件,承載一個修訂版計數、總大小、一個每修訂版摘要清單、一個已歸類的事件時間軸,以及每個物件的變更清單。

分析器是唯讀的。它從結構性標記偵測一個簽章修訂版的存在;它不驗證任何簽章、不重新計算任何摘要,也不檢查任何憑證。簽章驗證是一項獨立的 Core 能力。一份產生的報告是更新歷史在被剖析時的結構性描述;它不是文件真實、變更未經授權,或每一次修改都已被偵測的判定。請將該報告視為依分析器對修訂版鏈的視角所測得的防竄改證據偵測,而非一項鑑識保證或可呈堂的證明。

分析器刻意止步於結構。它回報修訂版鏈所含的內容,且絕不主張一個變更是經授權的或一個簽章是有效的。結構性存在與密碼學有效性是不同的主張;將兩者合併會讓一位呼叫者把防竄改證據誤認為一項保證。因此簽章有效性仍歸屬於單一的 Core 簽署介面,Forensics 與其組合而非複製。報告是可序列化為 JSON 的結構性中繼資料,因此一個 SIEM 可以在不觸及文件內容的情況下攝取編輯歷史。 設計背景:增量更新及其重要性

型別種類角色穩定度
ForensicAnalyzerclass剖析一份 PDF 並回傳一份鑑識報告(靜態 analyzestable1.10.0
ForensicReportclass分析結果;JsonSerializable 以供 SIEM 匯出stable1.10.0
RevisionSummaryclass每修訂版事實:物件計數、大小、位元組邊界、存在旗標stable1.10.0
ForensicEventclass帶有受影響物件清單的一個已歸類事件stable1.10.0
ForensicEventTypeenum事件類別(加入簽章、catalog 更新、新增物件等)stable1.10.0
ObjectChangeclass跨兩個修訂版、一個物件的變更紀錄stable1.10.0
ObjectChangeTypeenumAdded、Modified 或 Deletedstable1.10.0

ForensicReport 公開 hasIncrementalUpdates()hasAnySignature()getEventsByType()getChangesForRevision()jsonSerialize()。修訂版摘要上的 hasSignature 旗標是一個結構性存在訊號,而非一個有效性結果。

Analyze the revision history of a PDF
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Enterprise\Forensics\ForensicAnalyzer;
/**
* Produce a forensic report from PDF bytes.
*
* @param string $pdfData Raw PDF file bytes.
*
* @return array{revisions: int, incremental: bool, signedRevisionPresent: bool}
*/
function inspect(string $pdfData): array
{
$report = ForensicAnalyzer::analyze($pdfData);
return [
'revisions' => $report->revisionCount,
'incremental' => $report->hasIncrementalUpdates(),
'signedRevisionPresent' => $report->hasAnySignature(),
];
}

hasAnySignature() 回報的是結構中存在一個簽章修訂版。它不陳述該簽章是有效的。

Forensic analysis with SIEM export and fail-closed handling
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Enterprise\Forensics\ForensicAnalyzer;
use NextPDF\Enterprise\Forensics\ForensicEventType;
use Psr\Log\LoggerInterface;
final readonly class RevisionAuditor
{
public function __construct(private LoggerInterface $logger) {}
/**
* Analyze a document and emit a structural JSON record for the SIEM.
*
* @param string $pdfData The PDF bytes to inspect.
*
* @return string A JSON forensic report (no document content).
*/
public function audit(string $pdfData): string
{
try {
$report = ForensicAnalyzer::analyze($pdfData);
$this->logger->info('Forensic analysis complete', [
'revisions' => $report->revisionCount,
'sizeBytes' => $report->totalSizeBytes,
'signatureAddedEvents' => count(
$report->getEventsByType(ForensicEventType::SignatureAdded),
),
]);
return json_encode($report, JSON_THROW_ON_ERROR);
} catch (\Throwable $e) {
$this->logger->error('Forensic analysis failed', ['error' => $e->getMessage()]);
throw $e;
}
}
}

日誌紀錄僅承載計數與大小。它不承載文件文字。catch 區塊會重新拋出;它不吞掉剖析失敗。

  • 一份單一修訂版的文件沒有增量歷史。變更清單為空;這不是真實性的證據。
  • 一個 SignatureAdded 事件代表結構上存在一個簽章修訂版。它不是一個簽章有效性結果。請以 Core 簽署介面驗證該簽章。
  • 物件重用是正常的:一個被更新的物件會保留其物件編號,並附加一個新副本。分析器會將此回報為 Modified,而非移除與重新建立。
  • 一個 Deleted 歸類是交叉參照鏈中的一次 free-entry 轉換。讀取器仍可能解析該物件的較舊副本;結構層級的刪除並不保證不可復原。
  • 分析器回報的是剖析器所觀察到的。一份被精心製作以混淆剖析器的文件,可能產出一份與另一個工具視角不符的報告。該報告不是「每一次修改都已被偵測」的聲明。
  • 輸入是有界的。一份過大或修訂版過多的文件會以一個具型別的剖析例外 fail closed,而非耗用無限的記憶體。

分析成本隨修訂版計數與物件計數增加,而非隨渲染頁面複雜度增加。1500 ms 的牆鐘預算涵蓋一份典型的多修訂版商務文件。可重現性設定檔為 structural:對於給定的輸入,報告是確定性的,但絕對位元組偏移量反映的是確切的輸入檔案,無法在重新儲存的副本間移植。

分析器是唯讀的,且絕不寫入輸入。它是一個分析性介面,而非一個轉換性介面。它偵測簽章與加密標記的存在,但不執行任何密碼學運算,因此它不做任何 FIPS 聲明。一份報告描述的是被剖析的更新歷史;它不是一項真實性主張,且絕不可被呈現為防竄改、鑑識保證或可呈堂。是操作者下結論;函式庫回報結構。

分析在保有該 PDF 的主機上於行程內執行。沒有任何文件內容離開主機。報告承載物件編號、修訂版索引、大小、位元組邊界與事件類別——結構性中繼資料,而非文件文字或已偵測的個人資料。輸入 PDF 或報告本身是否含有個人資料,以及各自儲存於何處,是一項在函式庫邊界之外的部署責任。

函式庫會引發帶有結構性訊息的具型別例外,且不會將文件位元組置於例外文字中。一個在分析周圍進行日誌記錄的部署,應記錄報告的計數與類別——如正式環境範例所示——且絕不可將原始 PDF 酬載記錄到日誌或一個 APM 後端。JSON 報告是可安全轉送到 SIEM 的成品。

此模組中不發生任何密碼學運算,因此沒有任何 FIPS 模式特定行為。屬於密碼學的簽章驗證是一項獨立的 Core 能力,並在該處記載。

聲明標準條款
後續更新會將額外元素附加到檔案末尾;初始結構被後續更新修改。ISO 32000-2:2020§7.5.6
一個被更新的物件會被附加為一個新副本,且該更新的交叉參照項目會覆寫先前的位元組偏移量;讀取器會解析最新的副本。ISO 32000-2:2020§7.5.6
初始檔案結構可能被後續更新修改。ISO 32000-2:2020§7.5.4
一次更新的交叉參照區段只含有被新增、修改或刪除物件的項目。ISO 32000-2:2020§7.5.5
簽章字典記錄被簽署的內容。ISO 32000-2:2020§12.8.1
ByteRange 定義簽章所涵蓋的位元組範圍(簽章驗證是一項獨立的 Core 能力)。ISO 32000-2:2020§12.8.1
一個文件安全儲存區在較後的修訂版中存放長期驗證資料。ISO 32000-2:2020§12.8.4

所有條款皆為改寫。NextPDF 不重製規範性文字。請查閱已發布的標準以取得權威用語。NextPDF 不做任何鑑識認證聲明;報告描述的是被剖析的更新結構,而非一項對文件完整性的認證判定。

  • 分析器是唯讀的:它絕不寫入輸入文件,且不執行任何密碼學運算。
  • 它會剖析每個修訂版的交叉參照表、推導修訂版位元組邊界,並將每個物件歸類為新增、修改或刪除,然後將變更分組為一個已歸類的事件時間軸。
  • 一個 SignatureAdded 事件代表結構上存在一個簽章修訂版;它不是一個簽章有效性結果——驗證是一項獨立的 Core 能力。
  • 一份單一修訂版的文件有一個空的變更清單(不是真實性的證據);一個 Deleted 歸類是一次 free-entry 轉換,而非保證的不可復原。
  • 輸入是有界的:一份過大或修訂版過多的文件會以一個具型別的剖析例外 fail closed。該報告是依測得的防竄改證據偵測,而非一項鑑識保證或可呈堂的證明。

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

NextPDF Core(Apache-2.0)沒有修訂版歷史鑑識分析器——一個都沒有;此能力沒有 Core 層級的對應。Core 提供權威的簽章驗證介面,分析器與其組合,但不取代它。

NextPDF Pro 沒有修訂版歷史鑑識分析器——一個都沒有;此能力沒有 Pro 層級的對應。唯讀的修訂版與每個物件變更回報,以及可序列化為 JSON 的 SIEM 報告,僅隨 nextpdf/enterprise 套件提供。

修訂版剖析器、變更歸類,以及事件時間軸以行為層級描述。剖析器內部實作與任何內部歸類細節,皆不在公開介面範圍內。簽章有效性在此刻意不在範圍內——它是 Core 簽署介面的職責。

分析在保有該 PDF 的主機上於行程內執行;沒有任何文件內容離開主機。輸入 PDF 或報告是否含有個人資料,以及各自儲存於何處,是一項在函式庫邊界之外的部署責任。操作者從報告下結論;函式庫回報結構,且不主張文件真實性。

Forensics 介面不適用任何出口管制限制。該報告絕不可被呈現為防竄改、鑑識保證或可呈堂。本文件不是法律意見;請諮詢你自己的合規與法律顧問。