【问题标题】:Signed PDF is not LTV-ready签名的 PDF 未准备好 LTV
【发布时间】:2021-10-07 14:29:48
【问题描述】:

我正在尝试使用 BouncyCastle CMS 签署 PDF。签名有效,但 Adob​​e Reader 告诉我它还没有为 LTV 做好准备。

据我所知,CRL 嵌入在 CMS SignedData 中。证书也是嵌入的。还嵌入了时间戳。

签名是分离的签名,放在“预留空间”中。

为什么签名仍未准备好 LTV?我是不是在做一些明显的错误?

签名测试-PDF:http://www.filedropper.com/outputx

代码:

    CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
    // CertificateChain
    List<Certificate> certList = Arrays.asList(certChain);

    try {

        Hashtable signedAttrs = new Hashtable();
        X509Certificate signingCert = (X509Certificate) certList.get(0);
        gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC")
                .setSignedAttributeGenerator(new AttributeTable(signedAttrs))
                .build("SHA256withRSA", privKey, signingCert));

        gen.addCertificates(new JcaCertStore(certList));
        boolean embedCrls = true;
        if (embedCrls) {
            X509CRL[] crls = fetchCRLs(signingCert);
            for (X509CRL crl : crls) {
                gen.addCRL(new JcaX509CRLHolder(crl));
            }
        }
        // gen.addOtherRevocationInfo(arg0, arg1);

        CMSProcessableByteArray processable = new CMSProcessableByteArray(IOUtils.toByteArray(content));

        CMSSignedData signedData = gen.generate(processable, false);
        if (tsaClient != null) {
            signedData = signTimeStamps(signedData);
        }
        return signedData.getEncoded();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

【问题讨论】:

  • LTV 信息与AddValidationInformation.java 示例一起添加
  • 感谢 Tilman,我们(仍然)使用旧式 Adob​​e 签名。

标签: pdf pdf-generation pdfbox bouncycastle pkcs#7


【解决方案1】:

在可互操作的 PDF 签名中,有两种添加验证相关信息的方法,它们都没有使用默认的 CMS 方法来添加代码使用的 CRL。

在签名属性中添加预取数据

旧的 ISO 32000-1 样式“在 ISO 32000 中使用的 PKCS#7 签名”(后来基于 CMS 而不是 PKCS#7)被指定在专用的 signed 属性:

12.8.3.3.2 撤销信息

adbe 吊销信息属性:

adbe-revocationInfoArchival OBJECT IDENTIFIER ::=
                            { adbe(1.2.840.113583) acrobat(1) security(1) 8 }

吊销信息属性的值可以包括以下任何一种数据类型:

  • 证书撤销列表 (CRL),在 RFC 3280 中描述(参见参考书目):CRL 通常很大,因此不应嵌入到 PKCS#7 对象中。
  • 在线证书状态协议 (OCSP) 响应,在 RFC 2560,X.509 互联网公钥基础设施在线证书状态协议 - OCSP(参见参考书目)中描述:这些通常很小且在大小并且应该是包含在 PKCS#7 对象中的数据类型。
  • 自定义吊销信息:本规范未规定格式,除了将其编码为八位字节串。应用程序应该能够通过查看相关的 OBJECT IDENTIFIER 来确定 OCTET STRING 中包含的数据类型。

adbe 的 Revocation Information 属性值有 ASN.1 类型的 RevocationInfoArchival:

RevocationInfoArchival ::= SEQUENCE {
   crl [0] EXPLICIT SEQUENCE of CRLs, OPTIONAL
   ocsp [1] EXPLICIT SEQUENCE of OCSP Responses, OPTIONAL
   otherRevInfo [2] EXPLICIT SEQUENCE of OtherRevInfo, OPTIONAL
}
OtherRevInfo ::= SEQUENCE {
   Type OBJECT IDENTIFIER
   Value OCTET STRING
}

(显然这只是 Pseudo-ASN.1...)

由于此结构是已签名属性的值,因此必须在 签名之前获取吊销信息才能像这样添加。

在文档安全存储 (DSS) 中添加数据

对于他们的 PAdES 签名,ETSI 指定额外的 PDF 结构被添加到签名的 PDF 文档中,这些文件可以携带额外的验证相关信息,请参阅 ETSI EN 319 142。这些结构后来被集成到 ISO 32000-2 中:

12.8.4.3 文档安全存储 (DSS)

文档安全存储(DSS),当存在时,应该是一个字典,它应该是文档目录字典中的 DSS 键的值(参见 7.7.2,“文档目录字典” )。该词典可能包含:

  • 用于签名的所有证书的数组,包括文档中出现的时间戳签名。它还应持有验证参与证书链验证的证书所需的所有辅助证书。
  • 用于某些签名的所有证书撤销列表 (CRL)(参见 Internet RFC 5280)的数组,以及
  • 用于某些签名的所有证书状态协议 (OCSP) 响应(参见 Internet RFC 6960)的数组。
  • 一个 VRI 键,其值应该是一个字典,其中包含一个 VRI 字典(验证相关信息),用于以 CMS 格式表示的每个签名。

任何 VRI 字典(如果存在)应位于文档增量更新部分中。如果 VRI 字典应用的签名字典本身在增量更新部分,则 DSS/VRI 更新应晚于签名更新。 VRI 字典条目的包​​含是可选的。 VRI 条目中引用的所有验证材料也包含在 DSS 条目中。

...

正如您已经在此处阅读的,此结构设计用于在签名 之后添加信息。这与 ETSI 支持在签名后生成的撤销信息一起进行验证。

在 PDFBox 中

您在标签中提到了 PDFBox,因此您似乎使用 PDFBox 进行签名。

要将预取的验证数据添加到签名的adbe-revocationInfoArchival 属性,您只需将上面定义的属性添加到代码的signedAttrs

要在文档安全存储 (DSS) 中添加数据,您可以使用@Tilman 在评论中提到的 PDFBox 示例 AddValidationInformation 的代码。

【讨论】:

  • 啊,所以我犯了一个错误,认为 CMS 样式的 OID 会以某种方式与旧的 Adob​​e 样式签名一起使用。这就解释了为什么 addOtherRevocationInfo 也不起作用。将尝试手动将它们添加到 signedAttrs!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多