Sign concatenated PDF in append mode with CERTIFIE

2019-09-02 01:46发布

问题:

I tried to sign PDF with append mode and certification level CERTIFIED_NO_CHANGES_ALLOWED but certain PDF files shown as modified and therefore invalid in Acrobat.

itext 5.5.6, code:

PdfStamper stp = PdfStamper.createSignature(reader, os,'\0',null,true);
PdfSignatureAppearance app = stp.getSignatureAppearance();
app.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);

PDf file is created with wkhtmltopdf and concatenated with itself with pdfunite (CentOS 7)

Here is zip with sample PDF: https://www.dropbox.com/s/lea6r9fup6th44c/test_pdf.zip?dl=0

g.pdf - original PDF
2g.pdf - concatenated version (pdfunite g.pdf g.pdf 2g.pdf)
signed_g.pdf - original signed file, looks OK in Acrobat
signed_2g.pdf - concatenated signed file, looks like corrupted in Acrobat

So is it correct behavior, or something goes wrong with Acrobat, pdfunite, itext or myself )))?

Thanks.

回答1:

Certifying the sample 2g.pdf using the OP's code and verifying the result with other tools than Adobe Reader one obtains the information that the certification signature is valid.

Something like this (i.e. Adobe Reader complaining about a perfectly valid signature) usually happens with documents which cause Adobe Reader to manipulate the document upon loading. In such a case Adobe Reader checks the signatures in the changed document and, therefore, sees an invalid signature. Such manipulations may especially be repairs of invalid files.

This also is the case here, 2g.pdf is not completely valid (even though in a way that PDF parsers usually ignore): Its cross reference table is segmented into multiple subsections:

xref
0 1
0000000001 65535 f
3 2
0000000015 00000 n
0000000107 00000 n
6 41
0000000146 00000 n
...
0000015682 00000 n
48 14
0000015864 00000 n
...
0000025433 00000 n
66 2
0000025455 00000 n
0000025548 00000 n
69 41
0000025588 00000 n
...
0000041144 00000 n
111 14
0000041327 00000 n
...
0000050929 00000 n
126 4
0000050952 00000 n
0000051004 00000 n
0000051075 00000 n
0000051242 00000 n

But segmented cross reference tables are valid only in case of incremental updates, not in case of initial document revisions, and this document is constructed as an initial revision.

For a file that has never been incrementally updated, the cross-reference section shall contain only one subsection, whose object numbering begins at 0.

(section 7.5.4 Cross-Reference Table of ISO 32000-1)

Thus, this segmented table is invalid.

So I fixed the cross reference table to contain but one sub-section (by adding f (ree) entries for the indices left out: 2g-fix.pdf . And indeed, certifying this document using the OP's code one gets a certification signature Adobe Reader (at least version XI I've currently installed here) is happy with.

So this is the disadvantage of using incremental updates: One keeps the errors of the original document and has to cope with them...