I have created a PDF/A document using iText7. The created document has an attachment (). The attachment is a .csv file. Then the whole PDF/A has been signed. I have opened the attached .csv file and changed it after I have signed it. I have used following code to verify the signature:
public PdfPKCS7 verifySignature(SignatureUtil util, String name) throws GeneralSecurityException, IOException {
System.out.println("Signature covers whole document: " + util.signatureCoversWholeDocument(name));
System.out.println("Document revision: " + util.getRevision(name) + " of " + util.getTotalRevisions());
PdfPKCS7 pkcs7 = util.verifySignature(name);
System.out.println("Integrity check OK? " + pkcs7.verify());
return pkcs7;
}
I would have expected that integrity check returned error, but I got:
Signature covers whole document: false
Document revision: 1 of 2
Integrity check OK? true
Is this intended iText behavior and did I misunderstand the intention of a signature? I would expect the WHOLE document to be locked for changes (apart from filling forms or annotations if those are allowed).
What would be the best way to go about signing PDF with attachments in case I want to prohibit attachment changes?
To understand what happens here you have to know that there are multiple ways to save changes to a PDF:
You can simply save the manipulated PDF like a whole new document. Doing so will usually change the signed bytes making the Integrity check you ran fail.
Or you can add the changes as a so-called incremental update, i.e. append them to the PDF. Doing so will not change the signed byte range making the integrity check you ran succeed.
In your case the edit has been saved using an incremental update. This does not change the signed bytes; thus, the integrity check will succeed because it only checks whether the signature still correctly signs the originally signed byte ranges.
The coverage check (your
signatureCoversWholeDocument
call) on the other hand informs you that the signature in question does not cover the whole document anymore. Thus, you know that changes have been appended as incremental updates.Unfortunately iText does not yet offer a high level API to determine the nature of the changes introduced by an incremental update (the iText low level APIs can be used as a base upon which to implement such an API, though).
For some backgrounds on integrated PDF signatures you may want to read this answer and the documents referenced from there.
Technically you can add any kind of changes in an incremental update. Incremental updates are not only for use in storing allowed changes to signed documents, they can be used without signatures, too, e.g. to keep a revision history in the PDF or (saved separately) to allow resource efficient storage of PDF edits on WORM devices.
Thus, to determine whether changes to a PDF are allowed or not, the validator has to analyze the additions in the incremental updates.