How We Debugged a Customer Problem with a Signed PDF
When you contact the support team of any software company, you’d like that the person handling your support case is an expert in the kind of problem you’re facing. At PSPDFKit, we have deep expertise in the inner workings of the PDF format and can help you with even the strangest of problems, largely because our support people are the same engineers who build our products.
Case in point: One of our customers faced a problem with a PDF document that was signed multiple times. After signing the document the first time, it worked fine, but when the document was signed again, the previous digital signature appeared as invalid.
We’ve written a few blog posts about PDF digital signatures, so if you want a more detailed introduction to them, I recommend you read our introduction to digital signatures blog post. However, a succinct description of a PDF signature is that it’s a cryptography feature that verifies the authenticity of a PDF file and detects changes in it.
The Case of a Broken Signature When Signing a PDF More Than Once
A key aspect to understanding how digital signatures work is that each time you sign a PDF document, you add the signature information incrementally. This means that a new section is appended to the end of the PDF file without overwriting its previous content. So when you debug a problem with a PDF signature, you need to focus on the incremental sections of the PDF.
For the issue we were investigating, first, we opened the invalid signed document in a text editor and identified the incremental sections by searching for “%%EOF”. “%%EOF” is the keyword that identifies the end of an incremental section in a PDF, and the text between two consecutive “%%EOF”s is an incremental section. Each incremental section contains the definition of new or modified PDF objects that were added in that revision, and it also includes a new cross-reference table.
Once we identified all the incremental sections, we copied them to a separate file and deleted all of them except the one that contained the first digital signature. When doing this, it’s important to configure the text editor to not remove trailing whitespace when saving, because trimming whitespace on save will corrupt the PDF file.
Next, we added the incremental sections one by one until we identified the one that invalidated the digital signature.
A digital signature can be invalidated for two reasons:
-
The content that’s protected by the signature is modified.
-
The PDF modifications between signatures aren’t allowed (for example, the page contents were modified).
We knew that the content protected by the signature wasn’t modified because we were able to “fix” the digital signature by removing incremental sections. So what was left to do was check the content that was added between the first and the second digital signature. The rules about what kind of content you can add to a PDF after signing are, in general, complex (see 6.3.11 Controlling post-signing changes in the Adobe Digital Signatures in a PDF document), but for this particular case, they were the following:
-
You can fill form fields.
-
You can add new annotations.
-
You can add new digital signatures.
How We Fixed the Incorrect Incremental Section
This was the problematic section:
248 0 obj <</AA<</D 340 0 R >>/AP<</N 249 0 R >>/DA(/HeBo 12 Tf 0 g)/F 6/FT/Btn/Ff 65536/M(D:20200703092912Z)/MK<</I 335 0 R /IF<<>>/TP 1>>/P 177 0 R /Rect[ 323.134 21.265298 567.789 61.054704]/Subtype/Widget/T(Sample)/TU(Sample)/Type/Annot>> endobj xref 248 1 0000403378 00000 n trailer <</DecodeParms<</Columns 3/Predictor 12>>/Info 8 0 R /Root 173 0 R /Type/XRef/Size 372/Prev 402593/ID[<94EFF752DE577448984F3E414941B20D><78D31C09279AB1307E25ABB5B4D709ED>]>> startxref 403645 %%EOF `
This incremental section contained changes to a PDF button (PDF object number 248, 248 0 obj
). One thing we noticed is that all the updated properties of this PDF object were the same as they were in previous incremental saves, except for the modification time (/M(D:20200703092912Z)
), so we checked if removing the modification time fixed the problem.
You can perform basic PDF edits with a text editor, but you need to update the cross-reference table offset as well, so here’s how we did it: After we removed the /M
field with a text editor, we placed the cursor just before xref
and asked the text editor for the byte offset where the cursor was. Then, we replaced the 403645
just after startxref
with the new byte offset, and we saved the PDF.
After applying those changes, the first digital signature was valid, and adding a second one didn’t invalidate it. So, we were able to determine that the problem was caused by a change to the modification time that happened after the first digital signature was added and before the second one was added. This can happen when PDF software that doesn’t follow the PDF specification edits the document. We provided the customer with a corrected version of their document that they could sign again, and we also informed them of how they could avoid changing the form field’s modification time. Case closed.
Conclusion
This kind of systematic root case analysis is what you can expect if you reach the PSPDFKit support channels. We know the technical details of PDFs inside and out, so you don’t need to worry about them. Just focus on what makes your app unique and let us deal with the boring parts of PDF for you.
Are you interested in a PDF solution for your business but you don’t want to deal with the intricacies of this file format? Just contact our sales team.