user11465050
user11465050

Reputation: 15

Protect PDF file and "saveIncremental" in PDFBox

I'm trying to protect PDF file with permissions and passwords and then save it with "saveIncremental" method (because if signature is inside PDF file I want it to remain valid even after protection).

Here is code snippet:

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

I used this file.

Here are results - protected PDF file and same file after "allSecurityToBeRemoved".

User password is "user", owner password is "owner".

Problem is that protected file. Its content cannot be seen and signature is invalid and all signature info is showed in unreadable chars...

With "save" it works but with "saveIncremental" not. Is it possible to make it work with "saveIncremental" so signature remains valid? If yes, how?

I'm using PDFBox 2.0.7 and Adobe Acrobat Reader DC.

Thanks for all help!

Upvotes: 0

Views: 1895

Answers (1)

mkl
mkl

Reputation: 96064

@Tilman already presented the long and the short in a comment

so in PDFBox there is no way how to encrypt file with signatures so the signatures will remain valid?

Not incrementally. Not with PDFBox and not with another software. You'd have to encrypt at the beginning, i.e. when creating the PDF. (Or you encrypt and save normally, then reload and sign and save incrementally.

Here some explanations of the backgrounds:

When you sign a PDF, you usually first prepare it by adding a signature form field with a placeholder in the field value, then you cryptographically sign this prepared PDF minus the placeholder and inject the resulting signature into that placeholder. (In more detail here.) The result:

sketch of signed pdf

Thus, the signed bytes are the actual bytes in the serialized PDF file, not some (probably encryption agnostic) in-memory representation. So every change of these bytes will break the signature.

PDF encryption, on the other hand, must be applied in all document revisions identically: Either all revisions of a given PDF are encrypted (using the same password or certificate data) or none is, and this means that there is at least an Encrypt entry in the trailer of each revision.

Thus, if you encrypt a signed PDF, you automatically change some parts of the signed bytes, at least the trailer, so you break the signature.

What you can do, though, is encrypt and sign at the same time or first create an encrypted PDF and then sign it in an incremental update.

(Be aware, though, ISO 32000-1 in this regard is a bit sloppy and does not mention that the injected signature bytes must not be encrypted themselves. ISO 32000-2 has clarified this, but there now are some PDF validators out there that assume the signature bytes to be encrypted, and some that don't. In more detail here. Both encrypting and signing, therefore, might not be worth the trouble...)

Upvotes: 2

Related Questions