I've tried to sign pdf document using TCPDF in PHP. The signature seems work properly but after i send my base64 pdf file to TSA for timestamp the document. My Signature was invalid(in Adobe: The byte range is invalid). what is caused of the problem?
this is my byte range before timestamp /ByteRange[0 1208654 1220398 12856] this is my byte range after timestamp /ByteRange[0 1208655 1220399 12856]
(I used your latest files from the "PAdES(UTC datetime format)" folder for analysis but the result seems to apply to your previous attempts, too.)
This is extremely weird. Trial and error showed that the first bytes after the final "%%EOF" bytes of the original, signed revision can make Adobe Acrobat believe in some invalid ByteRange of the signature. This is not backed by the PDF specification.
Your signed (but not yet timestamped) PDF ends with the "%%EOF" bytes without a trailing end-of-line:
Adobe Acrobat validation is happy with this signature.
Then the timestamping service you use adds a CRLF end-of-line before adding its own objects as incremental update to your file:
Suddenly Adobe Acrobat calls the signature invalid because of an invalid ByteRange. But your signature covers the whole file (except the signature Contents value) with its byte range [0 1462644 1474388 12838]
, so the Acrobat error message "The signature byte range is invalid" clearly is wrong.
Timestamping your signed file with Adobe Acrobat on the other hand did not result in the same issue.
Comparing the files timestamped by your server and by Adobe Acrobat eventually (after analyzing many other differences) showed that a seemingly minor difference has a major impact, Acrobat only appends a single LF before its incremental update objects:
After replacing the CRLF (0D 0A) after the "%%EOF" in your timestamped signed file by e.g. CR SPACE (0D 20), Adobe Acrobat suddenly again is happy with the signature (obviously not with the timestamp anymore, after all I changed the timestamped revision).
Replacing with a SPACE LF (20 0A) on the other hand does not make Acrobat happy. Apparently the LF in the second byte after "%%EOF" triggers something in Adobe Acrobat which makes it think the preceding signature is invalid.
I don't remember having had this issue before. Usually, though, the signed PDFs I deal with already come with an end-of-line marker after the "%%EOF" included in the signed byte ranges. Thus, I assume the issue only comes up in case of signatures with byte ranges that end with "%%EOF" without an EOL, only for such files Acrobat appears to react weirdly.
Consequentially, you should add an EOL after the "%%EOF" before calculating the byte ranges and signing.
If that is not possible (e.g. due to restrictions of the PDF library you use), you can also consider to append a CR SPACE (0D 20) to your signed file before forwarding it to the timestamping service.
The underlying problem here is that the PDF specification is not entirely clear about whether the final "line" of the raw PDF with the "%%EOF" needs to be delimited with an EOL. I'm used to people consenting that both options, with and without an EOL, are allowed.
Adobe Acrobat here in its signature validation code seems to have a twisted idea on this topic, either due to an explicit test or due to a "repair" of the signed revision.