Enterprise 版本
Validation — 深入參考
Validation 模組會對原始 PDF bytes 執行預先建置的唯讀結構性合規原則。Compliance::assess() 會套用恰好一個 CompliancePolicy,並回傳一個附有依嚴重性分區的 findings 與強制法律免責聲明的 ComplianceReport。隨附的原則涵蓋 PDF/A-4(外加 e 與 f 變體)、PAdES baseline 結構、eIDAS 結構設定檔、LTV/DSS 健康、ZUGFeRD / Factur-X、FDA 21 CFR Part 11,以及 SEC Rule 17a-4 WORM 封存。每個原則都是純函式:輸入 bytes,輸出 findings。Validation 絕不變更文件,也絕不執行密碼學驗證。
可用性與授權
標題為「可用性與授權」的區段此能力隨附於 NextPDF Enterprise(nextpdf/enterprise),並以 Enterprise 層級的授權封套啟用。未持有該權益的部署不會載入此能力的類別。比較各版本並取得授權。
Validation/Evidence 範圍由 enterprise.compliance.evidence 能力授權。被拒的權益會拒絕該功能,而非默默降級。
| 層級 | Validation 範圍 |
|---|---|
| Core | 行程內的位元組串流驗證器與文法交叉檢查;零 finding 的結果是檢查結果,不是認證。 |
| Pro | 行程內於電子發票層級的 EN 16931 / Factur-X / ZUGFeRD 驗證;沒有預先建置的 PDF/A-4、PAdES、LTV、FDA 或 SEC 原則。 |
| Enterprise | 針對 PDF/A-4、PAdES、LTV、ZUGFeRD、FDA Part 11 與 SEC 17a-4 的預先建置結構性原則,附帶統一報告(本模組)。 |
Enterprise Compliance 的外部 sidecar 閘道是一個分開且獨立的模組。
公開 API 介面
標題為「公開 API 介面」的區段composer require nextpdf/enterprise:^3| 符號 | 參數 | 預設行為 | 回傳 | 拋出或失敗於 | 備註 |
|---|---|---|---|---|---|
Compliance::__construct | ?ClockInterface $clock = null | 未注入時鐘時使用系統時鐘 | — | — | 對 DI 友善的實例形式;時鐘會標記 validatedAt |
Compliance::run | string $pdfData、CompliancePolicy $policy、array $context = [] | 套用恰好一個原則並量測實際經過時間 | ComplianceReport | 傳遞自訂原則的例外;內建原則會收集 findings 而非拋出 | 實例方法 |
Compliance::assess(靜態) | string $pdfData、CompliancePolicy $policy、array $context = [] | 建構預設實例並委派給 run() | ComplianceReport | 與 run() 相同 | 零設定的捷徑 |
Policies::pdfA4 / ::pdfA4e / ::pdfA4f(靜態) | — | 依 ISO 19005-4:2020 的 PDF/A-4 結構性原則 | CompliancePolicy | — | e 允許 3D/富媒體註解;f 加入嵌入檔案關聯檢查 |
Policies::padesBaseline(靜態) | — | PAdES B-B 結構性檢查 | CompliancePolicy | — | 僅結構;無密碼學驗證 |
Policies::eidasQualified(靜態) | — | 在 eIDAS 標示設定檔下的 PAdES 結構性檢查 | CompliancePolicy | — | 合格性取決於 TSP 與合格憑證 |
Policies::ltvHealth(靜態) | — | DSS 結構健康檢查 | CompliancePolicy | — | DSS 存在性由作用中的物件圖解析,故障時關閉 |
Policies::zugferd(靜態) | string $profile = 'BASIC' | 正規化設定檔別名並建立 ZUGFeRD 驗證器 | CompliancePolicy | \ValueError(未知設定檔) | 設定檔:MINIMUM、BASIC、BASIC_WL、EN16931、EXTENDED |
Policies::fdaPart11(靜態) | — | FDA 21 CFR Part 11 結構性原則 | CompliancePolicy | — | 七項結構性檢查,包含稽核軌跡雜湊鏈完整性 |
Policies::sec17a4 / ::sec17a4Compatible / ::sec17a4Structural / ::sec17a4PreSign(靜態) | — | 具名嚴格程度的 SEC 17a-4 WORM 原則 | CompliancePolicy | — | 嚴格程度對應到 WormComplianceLevel |
CompliancePolicy(介面) | — | 單一標準的策略合約 | — | — | getName()、getIdentifier()、getStandardReference()、validate();可由客戶實作 |
ComplianceReport | 唯讀值物件 | findings 在建構時依嚴重性分區 | — | — | passes()、fails()、totalFindings()、getDisclaimer();公開 findings、errors、warnings、infos、policyName、policyId、standard、validatedAt、durationMs |
ComplianceFinding | Severity $severity、string $ruleId、string $message、string $clause = ''、string $suggestion = '' | 單一規則結果,附條款參照與修補提示 | — | — | 靜態 error() / warning() / info();isError() |
Severity(enum) | 3 個字串支援的案例 | Error、Warning、Info | — | — | 只有 Error 會讓報告失敗 |
WormComplianceLevel(enum) | 4 個字串支援的案例 | Full、Compatible、Structural、PreSign | — | — | requiresSignature()、requiresDocMdp()、requiresLtv()、maxDocMdpLevel() |
PdfAPolicy、PadesValidator、LtvHealthCheck、ZugferdValidator、Sec17a4WormPolicy、Fda\FdaPart11Policy | 各類別的建構式 | 各自為單一標準實作 CompliancePolicy | 由 validate() 回傳的 list<ComplianceFinding> | — | 透過 Policies 取得;Sec17a4WormPolicy::getLevel() 揭露設定的嚴格程度 |
Fda\FdaSigningIntent(enum) | 6 個字串支援的案例 | Authoring、Review、Approval、Certification、Verification、Rejection | — | — | toPdfReasonString() 產生正規的 /Reason 字串 |
Fda\FdaAuditEvent::__construct | DateTimeImmutable $timestamp、string $actor、FdaSigningIntent $action、string $documentHash、string $certificateSerial、string $previousEventHash = '' | 在建構時計算 SHA-256 鏈雜湊 | — | InvalidArgumentException(時間戳非 UTC) | 公開 eventHash;toXmpRdf() 序列化一個 XMP 清單項目 |
Fda\FdaAuditTrail::addEvent | FdaAuditEvent $event | 當事件的鏈結與軌跡尾端相符時附加該事件 | self | InvalidArgumentException(雜湊鏈斷裂) | 另有 createEvent()、verifyChain()、getLastEventHash()、getEvents()、embedInMetadata() |
Fda\FdaSignatureEnforcer::configureSeedValue | FdaSigningIntent $intent、string $tsaUrl | 建立受 FDA 約束的簽章種子值設定 | SeedValueConfig | — | 需要 FDA 原因集合、時間戳,以及 SHA-256 或更強的摘要 |
Fda\FdaSignatureEnforcer::applyTo | SequentialSigner $signer、SigningStrategy $strategy、string $signerName、FdaSigningIntent $intent、string $tsaUrl、string $fieldName = ''、?string $reason = null | 為 Pro 的 SequentialSigner 加入受 FDA 約束的簽署者 | SequentialSigner | — | 將約束序列化進產生的簽章欄位 |
namespace NextPDF\Enterprise\Validation;
final readonly class Compliance{ public function __construct(?ClockInterface $clock = null);
/** @param array<string, mixed> $context */ public function run(string $pdfData, CompliancePolicy $policy, array $context = []): ComplianceReport;
/** @param array<string, mixed> $context */ public static function assess(string $pdfData, CompliancePolicy $policy, array $context = []): ComplianceReport;}final class Policies{ public static function pdfA4(): CompliancePolicy; // also pdfA4e(), pdfA4f() public static function padesBaseline(): CompliancePolicy; public static function eidasQualified(): CompliancePolicy; public static function ltvHealth(): CompliancePolicy; public static function zugferd(string $profile = 'BASIC'): CompliancePolicy; public static function fdaPart11(): CompliancePolicy; public static function sec17a4(): CompliancePolicy; // also sec17a4Compatible(), sec17a4Structural(), sec17a4PreSign()}interface CompliancePolicy{ public function getName(): string;
public function getIdentifier(): string;
public function getStandardReference(): string;
/** * @param array<string, mixed> $context * @return list<ComplianceFinding> */ public function validate(string $pdfData, array $context = []): array;}
final readonly class ComplianceReport{ public const string LEGAL_DISCLAIMER;
public function passes(): bool;
public function fails(): bool;
public function totalFindings(): int;
public function getDisclaimer(): string;}行為合約
標題為「行為合約」的區段Compliance::assess()(靜態)與 Compliance::run()(實例,搭配可注入的 Psr\Clock\ClockInterface)會套用恰好一個原則並回傳一個 ComplianceReport。外部可觀察的規則:
- 純唯讀。 每個
CompliancePolicy::validate()都是純函式:輸入 bytes,輸出 findings。原則絕不變更 PDF bytes。這個架構不變量讓驗證與自動修正、以及 Evidence 模組保持區隔。 - 嚴重性閘門。
ComplianceReport::passes()只有在errors === []時為 true。warning 與 info 絕不會讓報告失敗。fails()是其補集。 - 強制免責聲明。
ComplianceReport::getDisclaimer()回傳常數的法律免責聲明文字。合約要求在面向使用者的輸出中顯示它。 - 報告出處。 報告會帶有來自原則的原則名稱、識別碼與標準參照、來自注入或系統時鐘的驗證時間戳,以及以毫秒量測的時長。
- 收集,而非中止。 內建原則會執行所有適用的檢查並收集每一個 finding,而不會在第一個 error 就停止。
- 僅限型錄可達的 DSS。
LtvHealthCheck會從作用中的物件圖解析 DSS 存在性:作用中的 trailer、接著/Root型錄、再接著/DSS及其子鍵。植入註解、字串、孤立物件或已被取代修訂中的標記 bytes 都不列入計算。無法解析的輸入會被視為沒有 DSS,因此檢查會故障時關閉。此檢查屬於結構性;它不會以密碼學方式驗證嵌入的 OCSP/CRL 資料。 - 結構性簽章檢查。
Policies::padesBaseline()與Policies::eidasQualified()僅在 PDF 層級驗證 PAdES 結構。eIDAS 下的合格性取決於 TSP 與合格憑證,而這些都在本模組之外。 - 受監管產業原則屬於結構性。
FdaPart11Policy會檢查簽章存在、/Reason意圖、/M簽署時間、/Name身分、無 JavaScript、FDA 稽核軌跡命名空間,以及雜湊鏈完整性。Sec17a4WormPolicy會檢查最多 13 條 WORM 規則;WormComplianceLevel選定嚴格程度。Full要求 DocMDP level 1、Compatible接受 level 2,而Structural/PreSign會略過簽章、DocMDP 與 DSS 規則。這兩個原則都不會建立法律合規。 - ZUGFeRD 情境。
Policies::zugferd()一律檢查 PDF 層級的需求。只有在呼叫者於$context中傳入['xml' => $xmlData]時才會驗證發票 XML;否則它會發出 info findingzugferd-xml-skipped。 - 防竄改稽核軌跡。
FdaAuditTrail是一條唯附加的 SHA-256 雜湊鏈。addEvent()會拒絕斷裂的鏈結,verifyChain()會重新推導每一個雜湊,而embedInMetadata()會將軌跡以 PDF/A 擴充結構描述寫入http://ns.nextpdf.dev/fda/1.0/底下的 XMP。
邊界案例與失敗模式
標題為「邊界案例與失敗模式」的區段- 在內建原則中,非 PDF 或空白輸入會產生 error findings,而非例外。請一律檢查
passes()並顯示免責聲明。 Policies::zugferd()會將設定檔別名(BASIC_WL、EN16931、EN_16931)正規化。未知的設定檔會在工廠時、於任何驗證執行之前引發\ValueError。- 有 CRL 但沒有 OCSP 回應的 DSS 會滿足撤銷資料檢查;該 finding 會註記此為可接受的替代方案。兩者皆無才是 error。
- 缺少
/VRI字典或/Certs陣列會產生 warning,而非 error;報告仍可通過。 FdaAuditEvent會在建構時以InvalidArgumentException拒絕任何非 UTC 時間戳。FdaAuditTrail::verifyChain()對任何被竄改或重新排序的事件都會回傳 false;它絕不拋出。- 自訂的
CompliancePolicy實作可能會從validate()拋出例外;Compliance::run()不會攔截,因此這類例外會傳遞給呼叫者。
FIPS 模式行為
標題為「FIPS 模式行為」的區段本模組不執行任何簽署、任何密碼學驗證,也不保管任何金鑰。FIPS 模式的演算法原則由 Security 與 Signature 模組治理。FdaSignatureEnforcer 的種子值會將受 FDA 約束的簽章欄位限制為 SHA-256、SHA-384 或 SHA-512 摘要方法。
一致性
標題為「一致性」的區段這些原則會針對具名標準檢查結構性屬性。ISO/ETSI 設定檔的一致性判定,仍是最終檔案加上外部驗證器的屬性。
| 行為 | 參照 |
|---|---|
| 一致性依該標準判定,而非由產生者判定 | ISO 19005-4:2020 §5.2 |
| 用於長期驗證的數位簽章字典 / DSS | ISO 32000-2:2020 §12.8 |
DSS 是由文件型錄的 DSS 鍵所持有的字典 | ISO 32000-2:2020 §12.8.4.3 |
| PAdES baseline 簽章層級 | ETSI EN 319 142-1 §5.4.3 |
| EN 16931 設定檔語意模型(輔助參考) | Factur-X 1.08 (EN 16931) |
FDA 21 CFR Part 11 與 SEC 17a-4 原則僅檢查結構性屬性;那些法規不在驗證語料庫之內,因此不帶有任何經驗證的一致性宣告。FDA findings 內的條款字串(例如 §11.50、§11.10(e))是由產品發出的規則參照。EN 16931 列是低於擷取門檻的輔助參考;它不是硬性一致性宣告。支援某項標準不等於符合該標準,而符合也不等於認證——NextPDF 並未持有任何認證,也不會授予任何認證。本參考不是法律意見;如需判斷法律上的充分性,請洽詢你的合規團隊。
開發註記
標題為「開發註記」的區段- Validation 會在行程內於本機執行,沒有任何網路 I/O。原則無法更動輸入。
- 請將來自不可信來源的 PDF bytes 視為具敵意。內建原則對任意 bytes 都是全域的,並在無法解析結構之處故障時關閉。
- 在每一個面向使用者的報告呈現中都要顯示
ComplianceReport::getDisclaimer()。 - 報告與 findings 可能帶有來自已簽署文件與稽核軌跡中繼資料的個人資料(簽署者名稱、憑證序號)。保留與最小化控制由操作者負責。
- 自訂原則會實作
CompliancePolicy;請讓getIdentifier()在所有原則之間維持唯一,以利序列化與快取。 - 本模組涉及密碼學功能;請在你自己的審查中將它視為安全敏感。
- 內部機制細節保留在原始碼儲存庫的內部文件中,不在本手冊的範圍內。
發佈邊界
標題為「發佈邊界」的區段本頁僅記載外部可觀察的行為與受支援的公開 API 介面。內部命名空間路徑、輔助類別、機制表格、runbook 檔名與工單前綴都不在範圍內。