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

问题描述 投票:4回答:1

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

然而,Acrobat告诉我我的签名是LTV启用的,但时间戳签名不是。

图片来自Acrobat Pro XI http:/img15.hostingpics.netpics727285so2.jpg。

这是因为时间戳证书的撤销信息没有嵌入到文档中。

缺少撤銷資訊 1 http:/img15.hostingpics.netpics491507so2a.jpg。

缺少撤销信息2 http:/img15.hostingpics.netpics312720so2b.jpg。

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

pdf itext
1个回答
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);
}

这段代码识别PDF中最近填写的签名字段,并检查它是文档时间戳还是普通签名。

如果是文档时间戳,代码只为这个文档时间戳添加验证信息。否则,该代码将为以下文档添加验证信息 签字。

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

只有做完这一切后,才会添加新的文档时间戳。

对于最终添加的时间戳,没有明确的验证信息被添加到PDF中(如果来自同一TSA的文件时间戳已经在短时间内被连续应用,则前一个时间戳的验证信息可能是适用的)。这也是为什么Adobe ReaderAcrobat通常不考虑启用这个文档时间戳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();
}

背景

为什么iText addLtv 这个例子并不(一定)创建支持LTV的PDF,因为它更接近ETSI在PAdES规范中提出的LTV最佳实践,而不是Adobe的LTV最佳实践。

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

Figure 2: Illustration of PDF Document with LTV

通过添加更多的 DSS 信息来验证之前的最后一个文档时间戳和一个新的文档时间戳,可以进一步延长保护的寿命,超过最后一个文档时间戳的寿命。图3对此进行了说明。

Figure 3: Illustration of PDF Document with repeated LTV

另一方面。据Adobe (2013年1月,他们的PDF布道者Leonard Rosenthol在iText邮件列表上写道。),

启用LTV意味着验证文件所需的所有信息(扣除根证书)都包含在其中。 因此,你的这句话将是真实的。

PDF是正确签署的,并且包含所有必要的证书,每个证书都有有效的CRL或OSCP响应。

但由于这个说法只有在DSS存在的情况下才是真的,所以你必须有DSS才会出现LTV-enabled。 不需要时间戳(常规或文件级别)。

由于这种分歧的PDF文件与LTV根据ETSI通常是由Adobe软件呈现有一个不LTV启用的文件时间戳。

参见

© www.soinside.com 2019 - 2024. All rights reserved.