使用 CERTIFIED_NO_CHANGES_ALLOWED 在追加模式下签署串联的 PDF

Sign concatenated PDF in append mode with CERTIFIED_NO_CHANGES_ALLOWED

我尝试使用附加模式和认证级别 CERTIFIED_NO_CHANGES_ALLOWED 签署 PDF,但某些 PDF 文件显示为已修改,因此在 Acrobat 中无效。

itext 5.5.6,代码:

PdfStamper stp = PdfStamper.createSignature(reader, os,'[=11=]',null,true);
PdfSignatureAppearance app = stp.getSignatureAppearance();
app.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);

PDF 文件是用 wkhtmltopdf 创建的,并用 pdfunite (CentOS 7)

这是带有示例 PDF 的 zip:https://www.dropbox.com/s/lea6r9fup6th44c/test_pdf.zip?dl=0

g.pdf - 原始 PDF
2g.pdf - 串联版本 (pdfunite g.pdf g.pdf 2g.pdf)
signed_g.pdf - 原始签名文件,在 Acrobat
中看起来不错 signed_2g.pdf - 串联的签名文件,在 Acrobat 中看起来像是损坏的

这是正确的行为,还是 Acrobat、pdfunite、itext 或我自己出了问题)))?

谢谢。

使用 OP 的代码验证示例 2g.pdf 并使用 Adob​​e 以外的其他工具验证结果 Reader 获得证明签名有效的信息。

类似这样的事情(即 Adob​​e Reader 抱怨完全有效的签名)通常发生在文档中,导致 Adob​​e Reader 在加载时操纵文档。在这种情况下,Adobe Reader 检查已更改文档中的签名,因此发现签名无效。此类操作尤其可能是修复无效文件。

这里也是如此,2g.pdf 并不完全有效(尽管 PDF 解析器通常会忽略这种方式):它的交叉引用 table 被分成多个小节:

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

但分段交叉引用table仅在增量更新的情况下有效,在初始文档修订的情况下无效,并且本文档构建为初始修订。

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)

因此,这个分段table是无效的。

所以我修复了交叉引用 table 以仅包含一个子部分(通过为遗漏的索引添加 f (ree) 条目:2g-fix.pdf 。事实上,使用 OP 的代码验证此文档可以获得 Adob​​e Reader(至少我目前在这里安装的版本 XI)满意的证书签名。

所以这是使用增量更新的缺点:一个人保留了原始文档的错误并且必须处理它们...