使用 openPDF 添加认证/docMDP 签名

Adding certification / docMDP signature using openPDF

我刚刚在创建 docMDP 时偶然发现了 openPDF 中的以下代码:

private void addDocMDP(PdfDictionary crypto) {
    PdfDictionary reference = new PdfDictionary();
    PdfDictionary transformParams = new PdfDictionary();
    transformParams.put(PdfName.P, new PdfNumber(certificationLevel));
    transformParams.put(PdfName.V, new PdfName("1.2"));
    transformParams.put(PdfName.TYPE, PdfName.TRANSFORMPARAMS);
    reference.put(PdfName.TRANSFORMMETHOD, PdfName.DOCMDP);
    reference.put(PdfName.TYPE, PdfName.SIGREF);
    reference.put(PdfName.TRANSFORMPARAMS, transformParams);
    reference.put(new PdfName("DigestValue"), new PdfString("aa"));
    PdfArray loc = new PdfArray();
    loc.add(new PdfNumber(0));
    loc.add(new PdfNumber(0));
    reference.put(new PdfName("DigestLocation"), loc);
    reference.put(new PdfName("DigestMethod"), new PdfName("MD5"));
    reference.put(PdfName.DATA, writer.reader.getTrailer().get(PdfName.ROOT));
    PdfArray types = new PdfArray();
    types.add(reference);
    crypto.put(PdfName.REFERENCE, types);
  }

这也将放入 PDF 中:

/Reference[<</DigestLocation[0 0] /TransformMethod/DocMDP /Type/SigRef /DigestMethod/MD5  
/DigestValue(aa) /TransformParams<</P 1/V/1.2/Type/TransformParams>>/Data 5 0 R>>]

我将 DigestMethod 更改为更新的内容,它确实有效。此外,'aa' 看起来非常静态,老实说就像一个虚拟实现。 关于这些价值观的任何见解?为什么可以毫无后果地改变它们? 我将它与它的前身 *text 5 进行了比较,但那里是一样的...

您的问题本质上不是关于 OpenPDF,而是关于 DocMDP 转换字典中的某些值。因此,我的回答不会集中在OpenPDF上。

在 PDF 版本 1.5 和 1.6 中,除了 字节范围摘要 之外,还使用了所谓的 对象摘要 和转换方法.这些摘要是根据相关转换的类型和参数在一组特定的 PDF 对象上递归计算的。

DigestMethod 值是在对象摘要中使用的哈希算法。

在 Adob​​e 的 PDF 参考 1.7 中,对象摘要已被弃用,这在勘误表中非常清楚:

在 ISO 32000-1 中,对象摘要已从文本中完全删除(在某些情况下会留下难以理解的文本)。

因此,您想知道的值已弃用,不再用于验证目的。

您还找到了 iText 在同一勘误表中使用虚拟值的原因:

因此,Adobe Acrobat 7 和 8 需要一些值。现在已经不需要了。


在此上下文中,您可能对 PDF issue 117 感兴趣 - DigestMethod 在 ISO 32000 中错误地变成了 required- 2:2020,这个问题是关于弃用它的。

所以在 openPDF 中我们可以采用这样的方法:

private void addDocMDP(PdfDictionary crypto) {
    PdfDictionary reference = new PdfDictionary();
    PdfDictionary transformParams = new PdfDictionary();
    transformParams.put(PdfName.P, new PdfNumber(certificationLevel));
    transformParams.put(PdfName.V, new PdfName("1.2"));
    transformParams.put(PdfName.TYPE, PdfName.TRANSFORMPARAMS);
    reference.put(PdfName.TRANSFORMMETHOD, PdfName.DOCMDP);
    reference.put(PdfName.TYPE, PdfName.SIGREF);
    reference.put(PdfName.TRANSFORMPARAMS, transformParams);
    reference.put(PdfName.DATA, writer.reader.getTrailer().get(PdfName.ROOT));
    PdfArray types = new PdfArray();
    types.add(reference);
    crypto.put(PdfName.REFERENCE, types);
}

我尝试并测试了它,*dobe 没有任何投诉 reader...