2
votes

I try to sign an encrypted PDF document for which the signature is allowed.
This document : Encrypted PDF document
With the PDFBox 2.0.0 sample code : CreateSignature.java

But I got this exception :

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)

I don't know the pass of the document but signing is allowed :

Document Restrictions Summary

What should I do for sign this document?

2
Indeed, I can reproduce the problem. After some debugging it looks to me like the PDFBox signing code has not been developed or tested for encrypted files. You may want to open an issue in the Apache PDFBox Jira. For the time being you might want to remove the password protection in a first step and only thereafter sign.mkl

2 Answers

1
votes

This has been fixed in PDFBox 2.0 RC3 (released today), please try it.

While the answer by Gleb is well-meant, it is not correct, due to the reasons I've written in the issue: https://issues.apache.org/jira/browse/PDFBOX-2729

The solution has the problem that it reads and saves the file first, so it is no longer the same before signing. Another problem is that we must encrypt with the same method than initially done, and with the same encryption key. For AES256, this (internal) encryption key has a random component, even if the user provides the same keys to the API.

0
votes

Here is my solution for this:

When you load your pdf file, check if it is protected, load it with Owner password and reset all security.

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

To make document protected again you should create new StandartProtectionPolicy with old passwords and premissions, save document, and then load it with password, sign it and save it again.

    .....
    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);

This works for me.