You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于iText7 Java的PDF云签名:如何启用LTV长期验证?

在iText7中为PDF数字签名启用LTV(长期验证)

要让PDF签名支持LTV,核心是把签名验证所需的长期有效性数据嵌入PDF的Document Security Store(DSS)中,这些数据包括OCSP响应、CRL证书吊销列表,以及证书链中必要的中间证书。以下是基于iText7的具体实现步骤:

1. 准备LTV所需的验证数据

首先要获取签名相关的所有验证数据:

  • 从云签名服务或CA官方接口,获取签名证书的OCSP响应(优先选择,因为体积小、时效性强)
  • 获取证书链中所有中间证书的OCSP响应或CRL
  • 如果使用私有CA,还需要根证书的CRL(公信任锚的根证书可省略)

注意:确保这些数据的有效期覆盖签名时间,且获取时间尽可能接近签名时间,避免验证失效。

2. 为已签名PDF添加LTV数据

如果已经完成签名,可事后通过LtvVerification类嵌入LTV数据:

// 打开已签名的PDF文件
PdfReader reader = new PdfReader("signed.pdf");
PdfDocument pdfDoc = new PdfDocument(reader, new PdfWriter("signed_with_ltv.pdf"));

// 初始化LTV处理器
LtvVerification ltv = new LtvVerification(pdfDoc);

// 目标签名字段(替换为你的签名字段名)
String signatureName = "MyDigitalSignature";
PdfSignatureField sigField = pdfDoc.getAcroForm().getSignatureField(signatureName);

// 获取签名的PKCS7对象(用于关联证书链)
PdfPKCS7 pkcs7 = sigField.getSignature().getPdfPKCS7();

// 假设已获取OCSP响应和CRL字节数组
byte[] ocspResp = ...; // 从云签/CA获取的OCSP响应
byte[] crlData = ...;  // 从CA获取的CRL数据

// 添加OCSP响应到LTV(覆盖整个证书链)
ltv.addVerification(
    signatureName,
    ocspResp,
    null,
    LtvVerification.CertificateOption.WHOLE_CHAIN,
    LtvVerification.Level.OCSP_CRL,
    LtvVerification.CertificateInclusion.NO
);

// 可选:添加CRL作为补充验证数据
ltv.addVerification(
    signatureName,
    null,
    crlData,
    LtvVerification.CertificateOption.WHOLE_CHAIN,
    LtvVerification.Level.OCSP_CRL,
    LtvVerification.CertificateInclusion.NO
);

// 将LTV数据写入PDF的DSS
ltv.merge();

// 关闭资源
pdfDoc.close();
reader.close();

3. 签名时直接启用LTV

如果要在签名流程中直接添加LTV,可在PdfSigner配置阶段集成:

PdfReader reader = new PdfReader("original.pdf");
PdfSigner signer = new PdfSigner(reader, new FileOutputStream("signed_with_ltv.pdf"), new StampingProperties());

// 配置签名字段和基本参数
signer.setFieldName("MyDigitalSignature");
signer.setCertificationLevel(PdfSigner.CERTIFIED_NO_CHANGES_ALLOWED);

// 初始化LTV处理器
LtvVerification ltv = new LtvVerification(signer.getDocument());

// 提前添加OCSP/CRL数据(同步骤2的配置)
ltv.addVerification("MyDigitalSignature", ocspResp, null, ...);

// 调用云签名服务完成签名(自定义IExternalSignature实现)
IExternalSignature cloudSignature = new CloudSignServiceSignature(); // 你的云签实现
signer.signDetached(
    cloudSignature,
    pkcs7.getCertificates(),
    null,
    null,
    null,
    0,
    PdfSigner.CryptoStandard.CMS
);

// 合并LTV数据到PDF
ltv.merge();

// 关闭资源
signer.close();
reader.close();

关键注意事项

  • 数据有效性:OCSP/CRL必须在签名时间点处于有效状态,且有效期足够长
  • 证书链覆盖:要确保所有非信任锚的证书(中间证书、签名证书)都有对应的验证数据
  • 时间戳:如果签名包含可信时间戳,LTV验证会依赖时间戳的时间来检查证书状态,需确保时间戳服务可靠
  • 云签对接:优先从云签名服务获取配套的OCSP/CRL数据,避免自己获取时出现时间或数据不匹配的问题

内容的提问来源于stack exchange,提问作者Wesley Alves

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:49:58