Enterprise 版本
Validation — 深度参考
Validation 模块针对原始 PDF 字节运行预置的、只读的结构性合规策略。Compliance::assess() 恰好应用一条 CompliancePolicy,并返回一个 ComplianceReport,其中包含按严重程度分区的发现项和一段强制法律免责声明。已提供的策略涵盖 PDF/A-4(外加 e 与 f 变体)、PAdES 基线结构、一个 eIDAS 结构性配置文件、LTV/DSS 健康检查、ZUGFeRD / Factur-X、FDA 21 CFR Part 11,以及 SEC Rule 17a-4 WORM 归档。每条策略都是一个纯函数:字节进,发现项出。Validation 绝不变更文档,也绝不执行密码学验证。
可用性与授权
标题为“可用性与授权”的章节此能力随 NextPDF Enterprise(nextpdf/enterprise)一起提供,并通过 Enterprise 层级的许可信封激活。缺少该授权的部署不会加载此能力的类。比较版本并获取授权。
Validation/Evidence 范围由 enterprise.compliance.evidence 能力授权。授权被拒会拒绝该功能,而非静默降级。
| 层级 | Validation 范围 |
|---|---|
| Core | 进程内的字节流验证器与一次语法交叉检查;零发现项的结果是被检查过的结果,而不是一份证书。 |
| 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 外部边车网关是一个独立、不同的模块。
公开 API 范围
标题为“公开 API 范围”的章节composer require nextpdf/enterprise:^3| 符号 | 参数 | 默认行为 | 返回 | 抛出或失败于 | 说明 |
|---|---|---|---|---|---|
Compliance::__construct | ?ClockInterface $clock = null | 未注入时钟时使用系统时钟 | — | — | 对 DI 友好的实例形式;该时钟为 validatedAt 打上时间戳 |
Compliance::run | string $pdfData, CompliancePolicy $policy, array $context = [] | 恰好应用一条策略并测量挂钟耗时 | ComplianceReport | 传播自定义策略的异常;内置策略收集发现项而非抛出 | 实例方法 |
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 的存在从活跃对象图中解析,失败即关闭(fail-closed) |
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 | 只读值对象 | 构造时按严重程度分区发现项 | — | — | 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(枚举) | 3 个字符串支撑的枚举项 | Error, Warning, Info | — | — | 只有 Error 会令报告失败 |
WormComplianceLevel(枚举) | 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(枚举) | 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()都是一个纯函数:字节进,发现项出。策略绝不变更 PDF 字节。这项架构不变式使验证有别于自动修复,也有别于 Evidence 模块。 - 严重程度门槛。 仅当
errors === []时ComplianceReport::passes()才为 true。warning 与 info 绝不令报告失败。fails()是其补集。 - 强制免责声明。
ComplianceReport::getDisclaimer()返回那段固定的法律免责声明文本。契约要求将其呈现在面向用户的输出中。 - 报告来源。 报告携带来自策略的策略名称、标识符与标准引用,来自注入时钟或系统时钟的验证时间戳,以及以毫秒计的所测耗时。
- 收集,而非中止。 内置策略运行所有适用的检查并收集每一个发现项,而不是在首个 error 处停止。
- 仅目录可达的 DSS。
LtvHealthCheck从活跃对象图中解析 DSS 的存在:活跃 trailer,然后是/Root目录,再然后是/DSS及其子键。植入注释、字符串、孤立对象或被取代版本中的标记字节不计数。无法解析的输入被视为没有 DSS,因此该检查失败即关闭。该检查是结构性的;它不对嵌入的 OCSP/CRL 数据做密码学验证。 - 结构性签名检查。
Policies::padesBaseline()与Policies::eidasQualified()仅在 PDF 层面验证 PAdES 结构。eIDAS 之下的合格性取决于 TSP 与合格证书,二者不在本模块之内。 - 受监管行业策略是结构性的。
FdaPart11Policy检查签名存在、/Reason意图、/M签署时间、/Name身份、无 JavaScript、FDA 审计追踪命名空间,以及哈希链完整性。Sec17a4WormPolicy检查多达 13 条 WORM 规则;WormComplianceLevel选择严格度。Full要求 DocMDP 级别 1,Compatible接受级别 2,而Structural/PreSign跳过签名、DocMDP 与 DSS 规则。两条策略都不确立法律合规。 - ZUGFeRD 上下文。
Policies::zugferd()始终检查 PDF 层面的要求。仅当调用方在$context中传入['xml' => $xmlData]时它才验证发票 XML;否则它发出 info 发现项zugferd-xml-skipped。 - 防篡改审计追踪。
FdaAuditTrail是一条仅追加的 SHA-256 哈希链。addEvent()拒绝断裂的链接,verifyChain()重新推导每一个哈希,而embedInMetadata()将该追踪以 PDF/A 扩展模式写入 XMP,位于http://ns.nextpdf.dev/fda/1.0/之下。
边界情形与失败模式
标题为“边界情形与失败模式”的章节- 在内置策略中,非 PDF 或空输入产出 error 发现项而非抛出异常。请始终检查
passes()并呈现免责声明。 Policies::zugferd()归一化配置文件别名(BASIC_WL、EN16931、EN_16931)。未知的配置文件会在工厂时、在任何验证运行之前引发\ValueError。- 一个带 CRL 但没有 OCSP 响应的 DSS 满足吊销材料检查;该发现项会记下这一可接受的替代。两者都不存在则为 error。
- 缺失
/VRI字典或/Certs数组产生 warning 而非 error;报告仍可通过。 FdaAuditEvent在构造时以InvalidArgumentException拒绝任何非 UTC 时间戳。- 对任何被篡改或重排序的事件,
FdaAuditTrail::verifyChain()返回 false;它绝不抛出。 - 自定义的
CompliancePolicy实现可能从validate()抛出;Compliance::run()不捕获,因此这类异常会传播给调用方。
FIPS-mode 行为
标题为“FIPS-mode 行为”的章节本模块不执行任何签名、任何密码学验证,也不进行任何密钥托管。FIPS-mode 算法策略由 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 基线签名级别 | 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 发现项中的条款字符串(例如 §11.50、§11.10(e))是产品发出的规则引用。EN 16931 一行是一项处于检索下限之下的支持性引用;它不是一项硬性符合性主张。支持某个标准不等于符合该标准,而符合也不等于认证——NextPDF 不持有任何认证,也不授予任何认证。本参考不是法律意见;请就法律充分性咨询你的合规团队。
开发说明
标题为“开发说明”的章节- Validation 在进程内、本地运行,没有任何网络 I/O。策略无法改变输入。
- 将来自不可信来源的 PDF 字节视为有敌意的。内置策略对任意字节都是全函数(total),并在无法解析结构处失败即关闭。
- 在报告的每一次面向用户的呈现中都呈现
ComplianceReport::getDisclaimer()。 - 报告与发现项可能携带来自已签名文件的个人数据与审计追踪元数据(签名者姓名、证书序列号)。运营方负责留存与最小化控制。
- 自定义策略实现
CompliancePolicy;为了序列化与缓存,请保持getIdentifier()在所有策略之间唯一。 - 本模块涉及密码学功能;在你自己的审查中将其视为安全敏感。
- 内部机制细节保留在源代码仓库的内部文档中,不在本手册的范围之内。
发布边界
标题为“发布边界”的章节本页仅记录外部可观察的行为与受支持的公开 API 范围。内部命名空间路径、辅助类、机制表、runbook 文件名与工单前缀不在范围之内。