如何为时间戳签名启用LTV?

Sil*_*las 4 pdf itext

我正在使用iText 5.5.3签署PDF文档.我需要将这些文档加上时间戳并启用LTV.我按照说明操作并使用了addLtv方法(代码示例5.9,Lowagie白皮书中的第137页).我得到一个带有2个签名的PDF,这是正常的:第一个是我自己的签名,第二个是文档级时间戳.

但是,Acrobat告诉我我的签名是启用了LTV,但时间戳签名不是:

来自Acrobat Pro XI的图片http://img15.hostingpics.net/pics/727285so2.jpg

这是因为时间戳证书的吊销信息未嵌入到文档中:

缺少撤销信息1 http://img15.hostingpics.net/pics/491507so2a.jpg

缺少撤销信息2 http://img15.hostingpics.net/pics/312720so2b.jpg

根据我的理解,addLtv方法应该获取所需的所有吊销信息并将其嵌入到文档中.这是正确的,还是我必须"手动"获取并嵌入这些信息?

mkl*_*mkl 10

这是这个问题的示例代码:

public void addLtv(String src, String dest, OcspClient ocsp, CrlClient crl, TSAClient tsa) throws IOException, DocumentException, GeneralSecurityException
{
    PdfReader r = new PdfReader(src);
    FileOutputStream fos = new FileOutputStream(dest);
    PdfStamper stp = PdfStamper.createSignature(r, fos, '\0', null, true);
    LtvVerification v = stp.getLtvVerification();
    AcroFields fields = stp.getAcroFields();
    List<String> names = fields.getSignatureNames();
    String sigName = names.get(names.size() - 1);
    PdfPKCS7 pkcs7 = fields.verifySignature(sigName);
    if (pkcs7.isTsp())
    {
        v.addVerification(sigName, ocsp, crl,
            LtvVerification.CertificateOption.SIGNING_CERTIFICATE,
            LtvVerification.Level.OCSP_CRL,
            LtvVerification.CertificateInclusion.NO);
    }
    else
    {
        for (String name : names)
        {
            v.addVerification(name, ocsp, crl,
                LtvVerification.CertificateOption.WHOLE_CHAIN,
                LtvVerification.Level.OCSP_CRL,
                LtvVerification.CertificateInclusion.NO);
        }
    }
    PdfSignatureAppearance sap = stp.getSignatureAppearance();
    LtvTimestamp.timestamp(sap, tsa, null);
}
Run Code Online (Sandbox Code Playgroud)

此代码标识PDF的最近填充的签名字段,并检查它是文档时间戳还是通常的签名.

如果它是文档时间戳,则代码仅为此文档时间戳添加验证信息.否则,代码会添加所有签名的验证信息.

(这背后的假设工作流程是文档首先签署(用于认证和/或批准),然后文档进入LTV循环,添加验证信息和文档时间戳,但不再有通常的签名.您的工作流程可能会有所不同,因此也可能是你的程序逻辑.)

只有在完成所有这些操作后,才会添加新的文档时间戳.

对于最终添加的时间戳,没有明确地向PDF添加验证信息(如果来自相同TSA的文档时间戳已经连续应用,则可以应用先前时间戳包括的验证信息).这就是为什么Adobe Reader/Acrobat通常不会考虑启用此文档时间戳LTV的原因.

如果您还需要此最终文档时间戳的验证信息,只需将此方法(与上述方法相同,但不添加文档时间戳)应用于包含文档时间戳的文件:

public void addLtvNoTS(String src, String dest, OcspClient ocsp, CrlClient crl) throws IOException, DocumentException, GeneralSecurityException
{
    PdfReader r = new PdfReader(src);
    FileOutputStream fos = new FileOutputStream(dest);
    PdfStamper stp = new PdfStamper(r, fos, '\0', true);
    LtvVerification v = stp.getLtvVerification();
    AcroFields fields = stp.getAcroFields();
    List<String> names = fields.getSignatureNames();
    String sigName = names.get(names.size() - 1);
    PdfPKCS7 pkcs7 = fields.verifySignature(sigName);
    if (pkcs7.isTsp())
    {
        v.addVerification(sigName, ocsp, crl,
            LtvVerification.CertificateOption.SIGNING_CERTIFICATE,
            LtvVerification.Level.OCSP_CRL,
            LtvVerification.CertificateInclusion.NO);
    }
    else
    {
        for (String name : names)
        {
            v.addVerification(name, ocsp, crl,
                LtvVerification.CertificateOption.WHOLE_CHAIN,
                LtvVerification.Level.OCSP_CRL,
                LtvVerification.CertificateInclusion.NO);
        }
    }
    stp.close();
}
Run Code Online (Sandbox Code Playgroud)

背景

iText addLtv示例不(必然)创建支持LTV的PDF的原因在于它更接近ETSI在PAdES规范中提出的LTV的最佳实践,而不是Adobe的LTV最佳实践.

根据ETSI TS 102 778-4 V1.1.2(2009-12),应用LTV的PDF文档的结构如图2所示.

图2:使用LTV的PDF文档图示

保护的生命周期可以进一步延长超过上一个文档的生命周期时间戳,通过添加更多DSS信息来验证上一个上一个文档时间戳以及新文档时间戳.这在图3中示出.

图3:重复LTV的PDF文档图示

另一方面,根据Adobe(由他们的PDF传播者Leonard Rosenthol在2013年1月的iText邮件列表上撰写),

启用LTV意味着验证文件所需的所有信息(减去根证书)都包含在其中.所以你的陈述是真的.

PDF已正确签名,并包含所有必需的证书,每个证书的有效CRL或OSCP响应

但由于该语句的唯一方法是存在DSS,因此必须启用支持LTV的DSS. 不需要时间戳(常规或文档级别).

由于这种分歧,根据ETSI的带有LTV的PDF文档通常由Adobe软件提供,以具有一个不具有LTV的文档时间戳.

也可以看看