Java 使用PDFBox 2.0.0签署加密的PDF文档

Java 使用PDFBox 2.0.0签署加密的PDF文档,java,pdf,encryption,pdfbox,sign,Java,Pdf,Encryption,Pdfbox,Sign,我尝试对允许签名的加密PDF文档进行签名。 本文件: 使用PDFBox 2.0.0示例代码: 但我有一个例外: Exception in thread "main" java.lang.NullPointerException at org.apache.pdfbox.pdmodel.encryption.StandardSecurityHandler.computeRevisionNumber(StandardSecurityHandler.java:131) at org.a

我尝试对允许签名的加密PDF文档进行签名。
本文件:
使用PDFBox 2.0.0示例代码:

但我有一个例外:

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)
我不知道文件的通行证,但允许签字:


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

以下是我的解决方案:

加载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);

这对我有用

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

虽然Gleb的回答是善意的,但由于我在本期中所写的原因,它并不正确:


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

事实上,我可以重现此问题。经过一些调试后,我觉得PDFBox签名代码还没有开发或测试加密文件。您可能希望在Apache PDFBox Jira中打开一个问题。目前,您可能希望在第一步中删除密码保护,然后再签名。我不确定这是否总是正确的。。。当我知道的足够多的时候,我会把我的想法写在PDFBOX-2729上。这并不容易,因为即使Adobe Reader接受该文件,也并不意味着它是正确的:-(您应该能够在不解锁的情况下对加密的PDF文件进行签名。@Cyrilbermaud,是的,但这似乎是pdfbox的问题。这种解决方法有助于处理加密但未签名的文件,并且在您需要对加密文档进行第二次签名时失败。@Cyrilbermaud为什么能够在不解密的情况下对加密文件进行签名?签名本身(除了/Contents字符串)是加密的,因此需要一个密钥。请参阅PDFBOX-3173,其中包含加密签名的文件。它就像一个符咒!我只是对bouncycastle提供程序有问题。请检查。谢谢!