【免费下载链接】core
A modern PDF library for TypeScript. Parse, modify, and generate PDFs with a clean, intuitive API.
LibPDF 是一个面向 TypeScript 的现代 PDF 库,提供解析、修改与生成 PDF 的简洁直观 API,也内置了完整的 PAdES 数字签名能力。本文面向新手讲解 PDF 签名长期有效性:为什么普通签名会"失效"、B-LT 与 B-LTA 签名如何做到"永不过期",以及验证数据是如何存入 DSS(文档安全存储)的。
为什么普通 PDF 签名会"过期"?
一个常见的困惑是:我明明用合法证书签了名,为什么几年后 PDF 阅读器却提示"签名状态未知"?
原因藏在签名验证的链条里:
- 证书有效期:签名证书通常只有 1~3 年有效期,过期后阅读器无法确认"签名时证书是否有效"
- OCSP/CRL 服务下线:验证证书是否被吊销需要访问 CA 的在线服务,这些服务可能随时间关闭
- 中间证书缺失:当年能自动补齐的证书链,几年后可能不再可用
🔑 换句话说,签名能不能被信任,取决于验证数据是否"永远在线"。长期有效性(LTV, Long-Term Validation)的核心思路就是:在签名那一刻,把未来验证所需的一切证据一次性"冻结"进 PDF 文件里,让文件自己成为证据。
PAdES 签名级别一览:B-B / B-T / B-LT / B-LTA
LibPDF 遵循 PAdES(PDF 高级电子签名)标准的四个签名等级,在签名时通过level选项选择:
| 级别 | 名称 | 验证数据 | 适用场景 |
|---|---|---|---|
| B-B | 基础签名 | 仅证书链 | 简单审批,短期使用 |
| B-T | 带时间戳签名 | 证书链 + TSA 时间戳 | 需要证明"何时签署" |
| B-LT | 长期验证签名 | 额外内嵌 OCSP 响应、CRL、完整证书链(DSS 存储) | 证书过期后仍可验证 |
| B-LTA | 档案级签名 | B-LT + 文档时间戳(Document Timestamp) | 十年以上长期归档 |
💡 可以理解为:B-T 证明"我在这个时间签过",B-LT 额外证明"签名时证书是好的、没被吊销",B-LTA 则连"验证证据本身"也被时间戳封印,实现真正的无限期验证。
各级别的类型定义位于 src/signatures/types.ts,官方签名指南见 content/docs/guides/signatures/index.mdx。
B-LT 长期验证:签名时自动"打包证据"
当你以 B-LT 级别签名时,LibPDF 会在签名过程中自动完成三件事:
- 时间戳:向时间戳权威机构(TSA)申请 RFC 3161 时间戳令牌,证明签署时间
- 收集吊销证据:为证书链中的每一张证书获取当时的 OCSP 响应或 CRL(证书吊销列表)
- 写入 DSS:把证书、OCSP 响应、CRL 全部打包进 PDF 内部的 DSS 结构,并记录"哪个证据属于哪个签名"
这个收集过程由 LTV 数据采集器完成,它对签名和 TSL 时间戳令牌统一处理,内部还带 OCSP/CRL 缓存——多位签署人共享同一 CA 时不会重复请求网络,见 src/signatures/ltv/gatherer.ts。
const tsa = new HttpTimestampAuthority("https://freetsa.org/tsr"); const { bytes, warnings } = await pdf.sign({ signer, level: "B-LT", // 自动获取 OCSP/CRL 并写入 DSS timestampAuthority: tsa, });运行后,即使签名字体证书几年后过期、CA 的在线服务下线,验证器依然可以离线确认签名的有效性。完整可运行示例见 examples/07-signatures/sign-with-long-term-validation.ts——它还演示了一个很好的容错思路:B-LT 因网络失败时逐级回退到 B-T、B-B。
DSS 文档安全存储:验证数据的"家"
DSS(Document Security Store,文档安全存储)是 PDF 2.0 规范(第 12.8.4.3 节)定义的专用字典,就是存放长期验证数据的地方。它包含四类内容:
/Certs:验证所需的完整证书链(根证书、中间证书、签署证书)/OCSPs:签署时刻各证书的 OCSP 吊销状态响应/CRLs:证书吊销列表/VRI:验证关联信息,用签名内容字节的 SHA-1 哈希作为键,精确指明"这组证据对应哪一枚签名"
LibPDF 的 DSS 构建器负责创建和合并DSS:多枚签名先后写入时,证书、OCSP、CRL 都按 SHA-1 去重复用,不会越签文件越大,实现见 src/signatures/ltv/dss-builder.ts;VRI 键的计算规则在 src/signatures/ltv/vri.ts。
📌 对新手只需记住一点:看到 PDF 里有 DSS,就说明这是一枚"自带证据"的长期有效签名。
B-LTA 档案级签名:给证据本身再盖一个时间戳
B-LT 有一个理论上的缺口:DSS 里的 OCSP 响应本身也有有效期。如果归档期限非常长(十年、二十年),到验证时 OCSP 响应本身也可能"过期"。
B-LTA 的解法是追加一枚文档时间戳(/Type /DocTimeStamp):
- 它的
ByteRange覆盖整个文档(包括已有的签名和 DSS) - 相当于 TSA 对整个文件状态"拍照存档":只要时间戳令牌本身可信(其证书链和吊销数据也会内嵌),就能证明"验证证据在 T 时刻已存在",从而支持无限期的再时间戳滚动
const { bytes } = await pdf.sign({ signer, level: "B-LTA", // B-LT 全部能力 + 文档时间戳 timestampAuthority: tsa, });文档时间戳的创建逻辑见 src/signatures/timestamp.ts,示例项目见 examples/07-signatures/sign-archival.ts。
多人签署后统一归档:addValidationData 与 addArchivalData
实际业务中更常见的流程是:多位签署人先后签字(用轻量的 B-T 级别,快且每人不用查吊销状态),全部签完后再一次性升级为档案级。LibPDF 为此提供了三个高层方法,实现在 src/api/pdf-signature.ts:
| 方法 | 作用 | 等效结果 |
|---|---|---|
pdf.addValidationData() | 为文档内所有已签签名批量收集 LTV 数据,写入单个 DSS 增量更新 | B-T → B-LT |
pdf.addTimestamp() | 追加覆盖全文档的 DocTimeStamp,封印此前所有签名 | 加上档案时间戳 |
pdf.addArchivalData() | 一步完成上面两步,并内嵌时间戳自身的验证数据 | 完整 B-LTA 归档 |
// 所有签署人签完后,一次调用完成档案级封存 const tsa = new HttpTimestampAuthority("https://freetsa.org/tsr"); const { bytes, warnings, signatureCount } = await pdf.addArchivalData({ timestampAuthority: tsa, });这些方法只在能增量保存的文档上工作;如果文档无法增量更新(如线性化文档),会抛出SignatureError拒绝执行——因为全量重写会使所有现有签名作废。集成测试用例可参考 src/integration/signatures/lta-finalization.test.ts。
常见陷阱与最佳实践
- ⚠️必须增量保存:签名后的文档只能追加更新,任何全量重写都会让签名失效
- 🌐LTV 需要网络:B-LT/B-LTA 要在签名时访问 OCSP/CRL 服务器,离线环境请提前规划
- 🩹失败后别复用实例:若
addTimestamp()等方法在部分进度后抛错(如 TSA 不可达),内存中的 PDF 实例可能已不同步,请丢弃该实例,用PDF.load()从最后已知的字节重新加载 - 🕐TSA 选择:生产环境建议使用证书提供商的官方时间戳服务器(DigiCert、Sectigo 等),免费服务如 FreeTSA 适合开发测试
- 🔁归档再时间戳:B-LTA 文档随时间推移可由验证器追加新的文档时间戳,实现滚动续命
快速上手清单
- 用
P12Signer或CryptoKeySigner加载证书(支持 Google KMS 企业密钥) - 选择级别:短期审批用 B-T,需要长期验证直接用 B-LT
- 多人签署流程最后调用
addArchivalData()一键升级到 B-LTA - 用 Adobe Reader 打开确认签名状态,检查 warnings 输出
更多签名玩法(P12 签名、KMS 签名、时间戳服务)可查阅官方指南 content/docs/guides/signatures/index.mdx 与示例目录 examples/07-signatures/。
【免费下载链接】core
A modern PDF library for TypeScript. Parse, modify, and generate PDFs with a clean, intuitive API.
相关推荐
OneUptime SSL 证书监控完整指南:证书有效期、自签名与有效性验证实战
OneUptime SSL 证书监控完整指南:证书有效期、自签名与有效性验证实战 SSL/TLS 证书过期是导致生产服务中断的最常见原因之一。OneUptime
可观测性后端运维前端云原生微服务AI AgentBentoPDF 数字签名验证实战:在浏览器中校验 PDF 签名完整性、证书有效期与信任链
BentoPDF 数字签名验证实战:在浏览器中校验 PDF 签名完整性、证书有效期与信任链 本文以 BentoPDF(Privacy First PDF Too
前端Mermaid Live Editor完全指南:免费在线图表编辑器的终极使用教程
Mermaid Live Editor完全指南:免费在线图表编辑器的终极使用教程 还在为复杂的图表制作工具而烦恼吗?想要一个简单、免费且功能强大的 在线图表编辑
前端开发者工具数据可视化
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考