我试图用权限和密码保护PDF文件,然后用"saveIncremental“方法保存它(因为如果签名在PDF文件中,我希望它在保护之后仍然有效)。
下面是代码片段:
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));
}我用的是这个文件。
这里是受结果保护的PDF文件和"allSecurityToBeRemoved“之后的相同文件。
用户密码是“用户”,用户密码是“所有者”。
问题是那个受保护的文件。它的内容无法看到,签名是无效的,所有的签名信息都显示在不可读的字符中。
对于“保存”,它是有效的,但与"saveIncremental“不起作用。是否有可能使它与"saveIncremental“一起工作,从而使签名仍然有效?如果是,怎么做?
我正在使用PDFBox 2.0.7和。
谢谢你的帮助!
发布于 2019-07-22 11:13:12
@Tilman已经在一条评论中给出了“长与短”
因此,在PDFBox中,没有办法用签名加密文件,这样签名才能保持有效?不是增量式的。不是用PDFBox,也不是用另一个软件。您必须在开始时加密,即在创建PDF时。(或者您通常加密和保存,然后重新加载、签名和增量保存。
以下是对背景的一些解释:
在签署PDF时,通常首先通过在字段值中添加带有占位符的signature字段来准备它,然后加密地对这个准备好的PDF减去占位符进行签名,并将得到的签名注入到该占位符中。(更详细地介绍这里。)结果:

因此,有符号字节是序列化PDF文件中的实际字节,而不是内存中某些(可能与加密无关)的字节。因此,这些字节的每一个变化都会破坏签名。
另一方面,PDF加密必须完全相同地应用于所有文档修订:给定PDF的所有修订要么加密(使用相同的密码或证书数据),要么没有加密,这意味着每个修订版的预告片中至少有一个加密条目。
因此,如果加密有签名的PDF,就会自动更改签名字节的某些部分(至少是预告片),从而破坏签名。
但是,您可以同时加密和签名,或者首先创建加密的PDF,然后在增量更新中对其进行签名。
(但是要注意,在这方面,ISO 32000-1有点草率,没有提到注入的签名字节本身不能加密。ISO 32000-2已经澄清了这一点,但是现在有一些PDF验证器假定签名字节被加密,还有一些没有加密。更详细的是这里。因此,加密和签名都不值得.)
https://stackoverflow.com/questions/57075883
复制相似问题