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

iText实现Certification签名LTV启用后PDF显示未修改状态的技术咨询

解决Certification签名添加LTV后PDF显示允许修改的问题

我之前也碰到过类似的情况,核心问题出在你先做Certification签名,再用PdfStamper追加LTV信息的流程上——这种方式本质是对PDF做了一次增量修改,而Certification签名默认或你设置的权限允许这类修改,所以Adobe Reader会提示“已进行认证方允许的更改”。要让PDF显示“签名后文档未被修改”,必须把LTV验证材料直接嵌入到Certification签名的容器里,而不是事后追加。

问题原因拆解

当你用PdfStamper单独添加LTV时,相当于在Certification签名之后给PDF加了新的验证信息对象,属于PDF的后续修改。哪怕你设置了Certification权限为允许填充/注释,这类LTV操作也会被判定为“允许的修改”,从而触发提示。只有当整个签名流程(包括LTV材料)一次性完成,没有后续增量更新时,才会显示“未被修改”。

解决方案:在Certification签名时嵌入LTV材料

你需要调整代码,把OCSP响应和CRL数据直接包含在Certification签名的PKCS7容器中,而不是事后用PdfStamper追加。具体步骤如下:

1. 修改Certification签名的创建流程

先设置文档的Certification权限(建议设为不允许任何修改,确保后续无变更),然后在签名过程中嵌入LTV验证材料:

using (PdfReader reader = new PdfReader(src))
using (FileStream os = new FileStream(dest, FileMode.CreateNew))
{
    // 创建签名Stamper,指定做Certification签名
    PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
    PdfSignatureAppearance appearance = stamper.SignatureAppearance;
    
    // 设置签名位置和名称
    appearance.SetVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "CertificationSignature");
    // 设置Certification级别:不允许任何修改(如果需要允许后续签名,可设为CERTIFIED_FORM_FILLING_AND_ANNOTATIONS,但要确保LTV嵌入签名内)
    appearance.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED;

    // 准备你的签名密钥、证书链、OCSP和CRL数据
    IExternalSignature signature = new PrivateKeySignature(privateKey, "SHA256");
    X509Certificate[] chain = ...; // 你的证书链
    byte[] ocspBytes = ...; // 获取GlobalSign的OCSP响应字节
    byte[] crlBytes = ...; // 获取GlobalSign的CRL字节

    // 自定义外部签名容器,传入LTV材料
    IExternalSignatureContainer externalContainer = new EmbeddedLtvSignatureContainer(signature, chain, ocspBytes, crlBytes);
    MakeSignature.SignExternalContainer(appearance, externalContainer, 8192);
}

2. 实现包含LTV的外部签名容器

自定义EmbeddedLtvSignatureContainer类,在生成PKCS7签名时直接加入OCSP和CRL数据:

public class EmbeddedLtvSignatureContainer : IExternalSignatureContainer
{
    private readonly IExternalSignature _signature;
    private readonly X509Certificate[] _chain;
    private readonly byte[] _ocspBytes;
    private readonly byte[] _crlBytes;

    public EmbeddedLtvSignatureContainer(IExternalSignature signature, X509Certificate[] chain, byte[] ocspBytes, byte[] crlBytes)
    {
        _signature = signature;
        _chain = chain;
        _ocspBytes = ocspBytes;
        _crlBytes = crlBytes;
    }

    public byte[] Sign(Stream data)
    {
        // 计算数据摘要
        byte[] digest = DigestAlgorithms.Digest(data, _signature.GetHashAlgorithm());
        
        // 创建PKCS7对象并嵌入LTV材料
        PdfPKCS7 pkcs7 = new PdfPKCS7(null, _chain, _signature.GetHashAlgorithm(), false);
        pkcs7.SetExternalDigest(_signature.Sign(digest), null, _signature.GetEncryptionAlgorithm());
        
        // 添加OCSP响应和CRL到PKCS7中
        if (_ocspBytes != null && _ocspBytes.Length > 0)
        {
            pkcs7.AddOcsp(_ocspBytes);
        }
        if (_crlBytes != null && _crlBytes.Length > 0)
        {
            pkcs7.AddCrl(_crlBytes);
        }

        // 生成包含LTV的PKCS7签名
        return pkcs7.GetEncodedPKCS7(digest, null, _ocspBytes, new List<byte[]> { _crlBytes }, CryptoStandard.CMS);
    }

    public void ModifySigningDictionary(PdfDictionary signDic)
    {
        // 设置签名类型为Adobe.PPKLite,子过滤器为adbe.pkcs7.detached
        signDic.Put(PdfName.FILTER, PdfName.ADOBE_PPKLITE);
        signDic.Put(PdfName.SUBFILTER, PdfName.ADBE_PKCS7_DETACHED);
    }
}

3. 移除后续的LTV追加代码

不再需要单独调用那段用PdfStamper添加LTV的代码,因为LTV材料已经嵌入到Certification签名里了。

关键注意点

  • Certification权限设置:如果你需要允许后续添加其他签名,可将CertificationLevel设为PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS,但必须保证LTV材料嵌入到初始的Certification签名中,不能事后追加。
  • OCSP/CRL获取:确保从GlobalSign获取的OCSP响应和CRL数据是有效的、未过期的,否则LTV验证会失败。

这样操作后,PDF的Certification签名本身就包含了所有LTV验证所需的材料,没有后续的修改操作,Adobe Reader就会显示“Document has not been modified since this signature was applied”。

内容的提问来源于stack exchange,提问作者Jitendra Bhargava

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:41:20