跳转到内容
getnextpdf.com

时间戳与可信时间

Spec: RFC 3161Spec: RFC 5816Spec: ISO 32000-2, §12.8.5

时间戳并不记录“这是何时签署的”。它证明的是更狭义、也更有力的事情:某一份特定数据在某个特定时刻之前就已存在,且这一点由签署者之外的第三方佐证。这个区别正是可信时间的全部价值所在,却也经常被误解。

签名内部的签署时间,只是签署者电脑声明的某个值。时钟可能因意外或蓄意操作而出错。如果何时的唯一证据只是签署者自己的主张,那么签署者就能随意把文件标成更早或更晚的日期。一张昨天才被撤销的证书,可以被伪装成仿佛去年就已签署。“何时”并不是细枝末节。它决定了使用现已过期或现已撤销的证书所生成的签名是否仍然有效。而一旦可信时间有误,建立在其上的每一项长期有效性论证都会随之崩溃。

  • 签署者自己的签署时间是一项主张,而非证明。它很容易被伪造。
  • RFC 3161 时间戳是来自时间戳机构(TSA)的已签名令牌,将你数据的哈希值绑定到 TSA 的时间
  • 它所证明的内容很精确:该数据在 TSA 所载明的时间之前就已存在。这并不是确切的创建时刻,而是一个上界。
  • 该令牌会回显你的 nonce(随机数)与你的消息印记,因此它不可能是重放,也不可能对应到其他数据。
  • 文件时间戳将同样的机制应用到整份 PDF,把其覆盖的所有内容——签名及其内嵌的验证证据——锚定到一个可信的时刻。

NextPDF 将时间戳视为需要验证的对象,而不只是需要获取的对象。请求一个令牌,只是工作中相对次要的一半。引擎的立场是:未经验证的令牌不构成证据。

当引擎为一个签名加上时间戳时,它会向 TSA 发送数据的哈希值与一个全新的随机 nonce,而绝不会发送数据本身。随后,返回的令牌会逐项比对使其具有意义的完整属性集:机构状态为“granted”、令牌中的 nonce 与送出的 nonce 相符、令牌中的消息印记与送出的哈希值相符、令牌本身的密码学签名通过验证、令牌的内容类型为时间戳类型,且所载明的时间落在可接受的容差范围内。任何不符都会构成带有分类原因的硬性失败。并不存在“看起来足够接近”的通融路径。文件时间戳遵循同样的规则,只是应用于整份文件,而非单个签名值。

两侧的设计刻意保持对称。当引擎为一个签名加上时间戳时,它送给 TSA 的印记就是签署者签名值的哈希值;而当它随后验证该时间戳时,会重新计算同样的哈希值,并要求令牌中的印记与之相符。NextPDF 将验证的这一半公开为一个专门的 verifySignatureTimestamp 步骤,该步骤把签名值作为必需的输入——因此,一个签名时间戳绝不可能在未真正检查其所覆盖内容的情况下被“验证”。该步骤在遇到空输入、无法识别或过弱(SHA-1)的印记算法、格式错误的印记,或未绑定签名值的哈希值时,都会失败关闭(拒绝通过)。因此,由某个对不同输入进行哈希的引擎版本所生成的令牌,按设计就无法证明这一绑定关系。

  1. Hash the dataOnly a digest of the signature value (or the whole PDF, for a document timestamp) is computed — never the data itself.
  2. Send hash + nonceThe digest and a fresh random nonce go to the Time-Stamp Authority.
  3. TSA returns a tokenA signed token binds the digest to the TSA’s genTime and echoes the nonce.
  4. Verify the tokenStatus granted, nonce matches, message imprint matches, token signature verifies, time within tolerance.
  5. Conclude an upper boundThe data provably existed before the TSA’s stated time — attested by a party that is not the signer.
可信时间戳记如何取得、又证明了什么:将杂凑值加上一个 nonce 送给 TSA,TSA 回传一个将该杂凑值系结到其时间的已签署权杖,验证者在把它当成“数据在该时间之前已存在”的证明之前,会先确認此系结。

你不会亲手组装一个时间戳令牌。真正重要的是信任边界。TSA 是你需要配置并保护的对象,因为它的时间会成为你的证据。

<?php
declare(strict_types=1);
use NextPDF\Security\Signature\SignatureLevel;
// Asking for any level at or above B-T requires a TSA.
$level = SignatureLevel::PAdES_B_T;
$level->requiresTimestamp(); // true → a Time-Stamp Authority must be supplied
// The TSA endpoint, its transport security, and its trust anchor are
// deployment-supplied. The engine sends a hash plus a fresh nonce — never the
// document — and verifies the returned token before the signature is accepted.
// A token that fails any check (status, nonce, imprint, signature, time)
// is a hard error, not a warning.

值得留意的边界在于:引擎送出的是哈希值,而非文件,因此 TSA 永远看不到你的内容。而且它会验证响应。一个你无法验证身份的 TSA,并不是可信时间。它只不过是另一个时钟。

陷阱在于把时间戳读成“这份文件正是在这一天的 14:32 签署的”。它并不是为签署事件计时的秒表。它证明的是数据不晚于 TSA 的时间就已存在,而这是由第三方设定的上界。创建时间可能是那之前的任何时刻。第二个陷阱是假设任何时间戳服务器都能给你可信时间。一个你无法验证其签名,或其证书颁发机构并不受你信任的令牌,什么都证明不了。它是一个你没有理由相信的时钟。可信时间来自一个你能验证身份的 TSA,以及一个你已验证过的令牌,而不是来自向服务器索取一个数字这个动作本身。

NextPDF 会构建请求、只送出哈希值,并验证返回的令牌。它并不为其背后的证书颁发机构背书。TSA 的准确度、它自身证书的有效性,以及它的可信度,都是该服务与你部署配置的属性,而非引擎的属性。时间戳将一个哈希值绑定到一个时间。它对数据的意义、签署者的身份,或签署者的证书是否有效,都一概不予置喙。那些属于另外的检查,涵盖于 正确验证签名。引擎无法把一个不可信的 TSA 变得可信。本页也并未主张时间戳具有任何特定的法律效力;那取决于 TSA 的状态与司法管辖区。可信时间如何被重复运用,以在数十年间保持签名可验证,这在 长期验证 中有说明。

时间戳记功能的版本层级供应情形:

RFC 3161 timestamping (signature timestamp and document timestamp) — edition availability
EditionAvailability
CoreNot in this edition
Pro

PAdES B-T — 针对签名值,使用由部署提供的 TSA 验证过的 RFC 3161 时间戳。

Enterprise

新增 B-LTB-LTA 所使用的文件时间戳,用以锚定内嵌的验证证据,并驱动归档更新循环。

  • 长期验证 — 文件时间戳如何封存内嵌证据,并随时间更新。
  • PAdES 基准配置文件 — 签名时间戳(B-T)与文件时间戳(B-LTA)在等级递进中各处于什么位置。
  • 合格签名说明 — 合格时间戳在 eIDAS 信任全貌中的定位。
  • 时间戳(RFC 3161 — 来自 TSA 的已签名令牌,将一份数据的哈希值绑定到 TSA 的时间,证明该数据在该时间之前就已存在。
  • 时间戳机构(TSA) — 签发时间戳令牌的可信服务。
  • TSTInfo — 令牌的内容结构:消息印记、生成时间、序号,以及选用的 nonce。
  • 消息印记 — 被加上时间戳的数据的哈希值,会在令牌中被回显。
  • Nonce — 随请求一同送出、并在令牌中被回显的全新随机值,使响应不可能是重放。
  • 文件时间戳 — 涵盖整份 PDF 的 RFC 3161 时间戳(按 RFC 5816 所更新),把签名及其证据锚定到一个可信的时刻。