【问题标题】:Protect PDF file and "saveIncremental" in PDFBox保护 PDF 文件和 PDFBox 中的“saveIncremental”
【发布时间】:2019-07-17 12:29:22
【问题描述】:

我正在尝试使用权限和密码保护 PDF 文件,然后使用“saveIncremental”方法保存它(因为如果签名在 PDF 文件中,我希望它即使在保护后仍然有效)。

这里是代码sn-p:

StandardProtectionPolicy standardProtectionPolicy = new StandardProtectionPolicy(ownerPassword, userPassword, accessPermission);

File protectedFile = new File(pdfFile.getParent(), substring + "_protected.pdf");

try (PDDocument document = PDDocument.load(pdfFile)) {

     document.protect(standardProtectionPolicy);

     SecurityHandler securityHandler = document.getEncryption().getSecurityHandler();
     if (!securityHandler.hasProtectionPolicy()) {
                throw new IllegalStateException("PDF contains an encryption dictionary, please remove it with "
                        + "setAllSecurityToBeRemoved() or set a protection policy with protect()");
     }
     securityHandler.prepareDocumentForEncryption(document);

     // update and save
     document.getDocument().getEncryptionDictionary().setNeedToBeUpdated(true);
     document.getEncryption().getCOSDictionary().setNeedToBeUpdated(true);

     COSDictionary encrypt = (COSDictionary) document.getDocumentCatalog().getCOSObject().getDictionaryObject(COSName.ENCRYPT);
     if (encrypt != null) encrypt.setNeedToBeUpdated(true);
     document.getDocumentCatalog().getPages().getCOSObject().setNeedToBeUpdated(true);
     document.getDocumentCatalog().getCOSObject().setNeedToBeUpdated(true);

     document.saveIncremental(new FileOutputStream(protectedFile));
}

我用this file

Here 是结果 - 受保护的 PDF 文件和“allSecurityToBeRemoved”之后的相同文件。

用户密码为“user”,所有者密码为“owner”。

问题是那个受保护的文件。其内容不可见,签名无效,所有签名信息都以不可读的字符显示...

使用“保存”它可以工作,但不能使用“saveIncremental”。是否可以使用“saveIncremental”使其签名保持有效?如果是,怎么做?

我正在使用 PDFBox 2.0.7 和 Adob​​e Acrobat Reader DC。

感谢大家的帮助!

【问题讨论】:

  • 当然不会... saveIncremental 不会加密现有的 PDF。它只能追加,所以这是一个可怕的混乱。
  • 并且当前版本是2.0.16。 (但它也不会在那里工作)
  • @TilmanHausherr 所以在 PDFBox 中没有办法用签名加密文件,所以签名将保持有效?
  • 不是增量的。不适用于 PDFBox,也不适用于其他软件。您必须在开始时加密,即在创建 PDF 时。 (或者你正常加密保存,然后重新加载签名,增量保存。

标签: java pdf pdfbox


【解决方案1】:

@Tilman 已经在评论中介绍了长和短

所以在 PDFBox 中没有办法如何使用签名加密文件以使签名保持有效?

不是渐进式的。不适用于 PDFBox,也不适用于其他软件。您必须在开始时加密,即在创建 PDF 时。 (或者你正常加密保存,然后重新加载签名,增量保存。

这里有一些背景说明:

签署 PDF 时,您通常首先通过在字段值中添加带有占位符的签名表单字段来准备它,然后对准备好的 PDF 减去占位符进行加密签名并注入生成的签名到那个占位符中。 (更详细的here。)结果:

因此,带符号的字节是序列化 PDF 文件中的实际字节,而不是某些(可能与加密无关的)内存表示。所以这些字节的每一次改变都会破坏签名

另一方面,

PDF 加密 必须以相同的方式应用于所有文档修订:给定 PDF 的所有修订都被加密(使用相同的密码或证书数据),或者没有,并且这意味着每个修订版的预告片中至少有一个 Encrypt 条目

因此,如果您对签名的 PDF 进行加密,您会自动更改签名字节的某些部分,至少是预告片,因此 您会破坏签名

不过,您可以做的是同时加密和签名,或者先创建一个加密的 PDF,然后在增量更新中对其进行签名。

(但请注意,ISO 32000-1 在这方面有点草率,并没有提到注入的签名字节不能自己加密。ISO 32000-2 已经澄清了这一点,但现在有一些 PDF 验证器那里假设签名字节被加密,而有些则没有。更详细的here。因此,加密和签名可能不值得麻烦......)

【讨论】:

  • 非常感谢您提供更详细的解释!我现在明白了...
猜你喜欢
  • 2012-10-15
  • 2022-10-04
  • 1970-01-01
  • 2017-08-24
  • 1970-01-01
  • 2012-09-05
  • 2012-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多