PDF/A 使用 iText7 签名允许在不破坏签名的情况下更改附加文档

PDF/A signed with iText7 allows changing attached documents without breaking a signature

我使用 iText7 创建了一个 PDF/A 文档。创建的文档有一个附件 ()。附件是一个 .csv 文件。那么整个PDF/A就已经签名了。我打开了附件中的 .csv 文件,并在签名后对其进行了更改。我使用以下代码来验证签名:

  public PdfPKCS7 verifySignature(SignatureUtil util, String name) throws GeneralSecurityException, IOException {
    System.out.println("Signature covers whole document: " + util.signatureCoversWholeDocument(name));
    System.out.println("Document revision: " + util.getRevision(name) + " of " + util.getTotalRevisions());
    PdfPKCS7 pkcs7 = util.verifySignature(name);
    System.out.println("Integrity check OK? " + pkcs7.verify());
    return pkcs7;
}

我原以为完整性检查会返回错误,但我得到了:

 Signature covers whole document: false
 Document revision: 1 of 2
 Integrity check OK? true

这是 iText 的预期行为吗?我是否误解了签名的意图?我希望整个文档都被锁定以进行更改(除了填写表格或注释,如果允许的话)。

如果我想禁止附件更改,使用附件签署 PDF 的最佳方式是什么?

要了解此处发生的情况,您必须知道有多种方法可以将更改保存到 PDF:

  • 您可以像保存一个全新文档一样简单地保存处理后的 PDF。这样做通常会更改签名字节,使 完整性检查 您 运行 失败。

  • 或者您可以将更改添加为所谓的增量更新,即将它们附加到 PDF。这样做不会更改带符号的字节 运行ge,从而使 完整性检查 您 运行 成功。

在您的情况下,编辑已使用增量更新保存。这不会改变带符号的字节;因此,完整性检查将成功,因为它只检查签名是否仍然正确地签署 原始签名字节 运行ges.

另一方面,覆盖率检查(您的 signatureCoversWholeDocument 电话)会通知您,有问题的签名不再覆盖整个文档。因此,您知道更改已作为增量更新附加。

遗憾的是,iText 尚未提供高级别 API 来确定增量更新引入的更改的性质(iText 低级别 API 可用作基础实现这样的 API,不过)。

对于集成 PDF 签名的一些背景知识,您可能需要阅读 this answer 和那里引用的文档。

I would expect the WHOLE document to be locked for changes (apart from filling forms or annotations if those are allowed).

从技术上讲,您可以在增量更新中添加任何类型的更改。增量更新不仅用于存储对签名文档的允许更改,它们也可以在没有签名的情况下使用,例如在 PDF 中保留修订历史记录或(单独保存)以允许在 WORM 设备上高效存储 PDF 编辑内容。

因此,为了确定是否允许对 PDF 进行更改,验证器必须分析增量更新中的添加。