跳转到内容

标准版图

Spec: ISO 32000-2 Spec: ETSI EN 319 142-1 Spec: RFC 3161 Spec: WCAG 2.2 Evidence: Standard-backed

PDF 引擎并不只对单个文件负责。它还要对一组由不同机构编写、彼此交叉引用的标准联邦负责。本页就是 NextPDF 所追踪的这套联邦地图,也是一条条款从「某项标准如此规定」走到「引擎如此实现,并有测试证明」的路径。

本页面向资深工程师:你需要先知道是哪一份文件在约束某项行为,再判断 NextPDF 对它的解读是否站得住脚。

「支持 PDF」这项主张隐藏了一个问题:到底支持的是什么。核心语法由 ISO 32000-2 定义。签名经由 ETSI 规范。时间戳是一套 IETF 协议。引擎渲染出的 HTML 与 CSS 属于 W3C 范畴。底层密码学则属于 NIST。输出的无障碍性又回到 W3C。

如果一个库把这些视为不可区分的一团整体,你就无法针对某次失败进行推理。当验证器拒绝一份已签署的发票时,第一个有用的问题并不是「这份 PDF 是不是坏了」,而是「没有满足的是哪一份标准的哪一条款,又是哪一方的问题」。要提出这个问题,你需要一张标明各机构的地图,以及一份诚实说明条款如何成为行为的记录。

  • NextPDF 追踪五个标准机构。ISO 负责格式本身。ETSI 负责欧洲的签名设定档。IETF 负责线路协议(时间戳,以及以引用方式纳入的密码学原语)。W3C 负责 HTML、CSS 与无障碍准则。NIST 负责经批准的密码学算法。
  • 这些文件构成的是轨迹,而非清单:单个已签署 PDF 能力会依序走过 ISO → ETSI → IETF → NIST,每一层都以规范方式引用下一层。
  • 条款不会因为被读过就变成行为。它是通过改写并引用、对应到需求、实现、再以测试固定才成为行为。描述该行为的页面会如实标明其证据等级。
  • 凡属强制的条款都会带有规范关键字(例如 shallmust)。NextPDF 把那些关键字视为契约。至于 should,它会将其记载为建议,而非保证。

ISO 32000-2 是核心。它定义了何谓兼容文件。兼容文件必须遵守该文件的每一项需求,同时可自由省略该文件未明确要求的任何功能 Spec: ISO 32000-2, §6 。它同时也对写入方规定了义务:NextPDF 在文件中创建或修改的任何内容,都必须符合格式,并与已存在的元素保持一致 Spec: ISO 32000-2, §6 。正是这一条款,使得引擎拒绝产出结构不一致的增量更新。这并非 NextPDF 的偏好,而是格式本身的规则。

从这个核心出发,ISO 32000-2 向外指引。它的签名处理通过「引用」来定义,指向用于 PAdES 的 ETSI EN 319 142 系列。ETSI 接着为时间戳令牌引用 IETF RFC 3161,并为哈希与签名算法引用 NIST FIPS 系列。因此,一项能力实际上是一条穿越多份文件的路径,每一份对自己所在层级而言都是规范性的。

  1. Step 1 of 5: ISO 32000-2 §12.8 signatures
  2. Step 2 of 5: ETSI EN 319 142-1 PAdES baseline
  3. Step 3 of 5: RFC 3161 timestamp token
  4. Step 4 of 5: NIST FIPS 180-4 hash strength
  5. Step 5 of 5: WCAG 2.2 tagged output
单一份可长期验证的已签署 PDF 所经过的标准轨迹:ISO 定义容器并指向 ETSI 取得签名设定档;ETSI 要求一个 IETF 时间戳记;密码学原语经 NIST 核可;算绘输出则受 W3C 无障碍标准约束。每一个箭头都是一项规范性引用,而非松散的关联。

标准工作的危险做法,是读完一条款后就凭记忆写代码。NextPDF 刻意采取较长的路径,因为较长路径才是可审计的路径:

  1. Retrieve The clause is read from the standard, not from memory.
  2. Cite It is paraphrased and pinned with a chunk digest, never quoted.
  3. Classify Its keyword (shall / should / may) sets whether it is a contract or a recommendation.
  4. Map The obligation becomes a concrete engine requirement.
  5. Implement The requirement is built into the pipeline.
  6. Pin A test holds the behaviour against drift.
  7. Tag The page that describes it declares its evidence level.
从规范条款到经过测试的引擎行为的路径:取得并引用该条款、依其规范关键字将其义务分类、对应到引擎需求、实作、以测试钉住,再为记载页面标上其证据依据。一条在测试之前就止步的条款,只是主张,而非行为。

「分类」这一步,正是大多数含混之处被厘清的地方。规范以关键字编码其需求等级:众所周知的 MUSTSHALLSHOULDMAY 这一家族。这些关键字的意义由 IETF 需求关键字惯例固定,并经更新以厘清只有大写形式才具规范性,再叠加到各规范的描述性文字之上 Spec: RFC 2119 Spec: RFC 8174 。 NextPDF 把 shall 读作引擎绝不跨越的硬性边界,而把 should 读作它会遵循、并以建议身份记载的建议—— 绝不当作承诺。这项区分,正是诚实的能力声明与过度宣称之间的差别。

「兼容」很少只是一个比特。签名标准是分级的——举例来说,欧洲的「长期含封存」设定档正是为了加入时间戳令牌而存在,让签名在创建后长期仍可验证 Spec: ETSI EN 319 122-1, §6 。这是一项比仅有基准签名严格得多的主张。无障碍标准同样如此:唯有满足某等级的每一项成功准则,才算达到该兼容等级,而一项主张须陈述其实际达到的等级 Spec: WCAG 2.2, §5.2.1 。因此 NextPDF 会陈述设定档等级,而非未经限定的「兼容」。

本页为 Evidence: Standard-backed :每一项主张都锚定到具体条款、经过改写,并附上摘要引用,让下一位审查者能对照原始来源重新验证。

层级机构锚定条款(改写)在 NextPDF 中规范什么
格式ISO写入方创建或修改的元素必须兼容并保持一致 Spec: ISO 32000-2, §6 引擎产出的 PDF
兼容性ISO兼容文件须满足所有需求;额外功能为选用 Spec: ISO 32000-2, §6 「有效输出」的含义
签名设定档ETSI「长期含封存」等级加入时间戳,供日后验证 Spec: ETSI EN 319 122-1, §6 签名锁定的 PAdES 设定档
可信时间IETF时间戳记服务证明某项数据在某一时间之前即已存在 Spec: RFC 3161, §2 文件时间戳记权杖
密码学NIST经批准的哈希在所提供的安全强度上各有不同 Spec: NIST FIPS 180-4, §1 签名底层的摘要算法
输出存取W3C某兼容等级要求满足该等级的每一项准则 Spec: WCAG 2.2, §5.2.1 针对渲染 PDF 的无障碍主张

所引用的摘要记录在本页的 citations frontmatter 中。此处并未重现任何标准的原文。关于这种选择的规则另有专页说明。请参阅 引用纪律

你并不会去「执行」标准版图;你会阅读它,用来决定该向引擎提出什么要求。具体来说,一次可长期验证的签署调用,实际上是在声明你需要轨迹上的哪一个点

examples/36-sign-pades-b-b-and-b-t.php
<?php
declare(strict_types=1);
use NextPDF\Core\Document;
use NextPDF\Security\Signature\CertificateInfo;
use NextPDF\Security\Signature\DigitalSigner;
use NextPDF\Security\Signature\SignatureLevel;
// The signature level is a coordinate on the ISO -> ETSI -> RFC trail.
// PAdES B-B is the ETSI baseline CMS SignedData the Core engine produces;
// B-T adds an RFC 3161 timestamp, and B-LT/B-LTA add the DSS and document
// timestamps that keep a signature validatable after the certificate
// expires. The level you name is the point on the trail you are asking for.
$certInfo = CertificateInfo::fromFiles(
certPath: 'signer-cert.pem',
keyPath: 'signer-key.pem',
);
// The functional signing path is the direct two-phase signing engine.
// (Document::setSignature() records intent but its writer seam is not yet
// wired and fail-fasts on output — see the PadesOrchestrator docblock.)
$signer = new DigitalSigner(
certInfo: $certInfo,
level: SignatureLevel::PAdES_B_B,
);
$result = $signer->sign(file_get_contents('agreement.pdf'));
printf(
"PAdES %s CMS: %d bytes, timestamp=%s\n",
SignatureLevel::PAdES_B_B->value,
$result->getSize(),
$result->hasTimestamp() ? 'yes' : 'no',
);

指定 PAdES_B_LTA 而非仅指定基准,并不是一个性能旋钮。它是一项决定:义务要沿标准轨迹延伸到多深。B-LT 与 B-LTA 会拉入 DSS 与封存时间戳记层,并在执行阶段需要企业版 LTV 套件。引擎不会默默降级,而是拒绝假装较低的等级能交付较高的等级。

陷阱在于把「NextPDF 符合标准」理解成单一且全面的保证。它并非如此,任何诚实的引擎也都不会这样承诺。兼容性是逐标准、逐条款、逐等级而论的。NextPDF 锁定 PDF 2.0 基准、具名的 PAdES 设定档,以及所陈述的无障碍等级——每一项都有范围、每一项都有引用。一项缺少条款与等级支撑的主张只是营销,而 Insider_ 不会发布它。

第二个更隐蔽的陷阱,是把规范性的 should 当成承诺。它是一项建议。NextPDF 会把建议记载为建议。引擎的保证由 shall 条款构建,而这项差别具有实质分量。

本页是地图,而非疆域本身。它并未列举 NextPDF 实现的每一条款,也不是一份兼容性证书。逐项行为的证明,存在于拥有该行为的主题页面上,并带有该页面自身的证据等级——例如格式差异请参见 PDF 2.0:有何变动

标准版图也会变动。新版本会发布。引用会被重新指向。此处所引用的条款,固定于本页 citations 中所记录的语料快照。当上游标准改版时,引用会对照新条款重新验证,而非径自假设沿用。凡本页提及进阶版(Premium)等级的能力,都只在它对应哪一份标准的层级上描述,绝不触及内部机制的层级。

  • 标准机构——发布规范的组织(ISO、ETSI、IETF、W3C、NIST)。它们分别负责 PDF 堆栈中的不同层级。
  • 规范条款——标准中的一项需求,以其关键字标示(shall/must 表示强制,should 表示建议,may 表示选用)。
  • 标准轨迹——单个能力所经过、有序的规范链,其中每份文件都以规范方式引用下一份。
  • 兼容等级——分级的兼容阶层(ETSI 基准设定档、WCAG 等级)。一项主张会陈述实际达到的等级,而非未经限定的「兼容」。
  • PAdES——PDF 高级电子签名(PDF Advanced Electronic Signatures),即 ETSI EN 319 142 系列的签名设定档,ISO 32000-2 引用它来进行 PDF 签署。