使用CERTIFIED_NO_CHANGES_ALLOWED在追加模式下对连接的PDF进行签名

时间:2015-05-29 09:41:54

标签: itext itextpdf

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

itext 5.5.6,代码:

PdfStamper stp = PdfStamper.createSignature(reader, os,'\0',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或我自己的问题)))?

感谢。

1 个答案:

答案 0 :(得分:2)

使用OP代码验证样本2g.pdf,并使用除Adobe Reader之外的其他工具验证结果,获取证书签名有效的信息。

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

这也是这种情况,2g.pdf不完全有效(即使PDF解析器通常忽略):它的交叉引用表被分段为多个子部分:

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

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

  

对于从未进行过增量更新的文件,交叉引用部分只应包含一个子部分,其对象编号从0开始。

     

(第7.5.4节ISO 32000-1的交叉引用表)

因此,此分段表无效。

所以我修改了交叉引用表,只包含一个子部分(通过为剩下的索引添加 f (ree)条目:2g-fix.pdf 。确实,证明了这个文档使用OP的代码获得认证签名Adobe Reader(至少版本XI我目前已安装在这里)很满意。

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