使用PDFBox 2.0.0对加密的PDF文档进行签名

时间:2015-03-24 12:29:52

标签: java pdf encryption pdfbox sign

我尝试签署允许签名的加密PDF文档 本文件:Encrypted PDF document
使用PDFBox 2.0.0示例代码:CreateSignature.java

但我得到了这个例外:

Exception in thread "main" java.lang.NullPointerException
    at org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler.computeRevisionNumber(StandardSecurityHandler.java:131)
    at org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler.prepareDocumentForEncryption(StandardSecurityHandler.java:335)
    at org.apache.pdfbox.pdfwriter.COSWriter.write(COSWriter.java:1254)
    at org.apache.pdfbox.pdmodel.PDDocument.saveIncremental(PDDocument.java:966)
    at principal.CreateSignature.signDetached(CreateSignature.java:179)
    at principal.CreateSignature.signDetached(CreateSignature.java:154)
    at principal.CreateSignature.main(CreateSignature.java:334)

我不知道文件的通过,但允许签名:

Document Restrictions Summary

我该怎么办才能签署这份文件?

2 个答案:

答案 0 :(得分:1)

这已在PDFBox 2.0 RC3(今天发布)中修复,请试试。

虽然Gleb的答案很明确,但由于我在问题中写的原因,这是不正确的: https://issues.apache.org/jira/browse/PDFBOX-2729

解决方案存在首先读取并保存文件的问题,因此在签名之前它不再相同。另一个问题是我们必须使用与最初完成相同的方法加密,并使用相同的加密密钥。对于AES256,此(内部)加密密钥具有随机组件,即使用户向API提供相同的密钥。

答案 1 :(得分:0)

以下是我的解决方案:

加载pdf文件时,检查它是否受保护,使用所有者密码加载并重置所有安全性。

         ...
        this.document = PDDocument.load(pdf, ownerPassword);
        document.setAllSecurityToBeRemoved(true);
        ...

要再次保护文档,您应该使用旧密码和预先设置创建新的StandartProtectionPolicy,保存文档,然后使用密码加载,签名并再次保存。

    .....
    StandardProtectionPolicy policy = new StandertProtectionPolicy(ownerPassword, userPassword, accessPremission)
       doc.protect(policy);
       doc.save(signedFile);
       doc.close();
       doc = PDDocument.load(signedFile, policy.getOwnerPassword());
       doc.protect(policy);
       ....
       doc.addSignature(signature, this, options);

这对我有用。