IText 从 SIGNED PDF 中提取原始文件并比较 HASH

IText Extract original from SIGNED PDF and compare HASH

我有一个签名的 PDF。签名覆盖整个文件,有效

我想提取原始 pdf 以将其哈希值与未签名 pdf 的哈希值进行比较。

我使用以下代码提取原始 pdf:

PdfReader reader = new PdfReader(FILESIGNED);
AcroFields acrofields = reader.getAcroFields();
//pdf have a unique signature
String signatureName = acrofields.getSignatureNames().get(0); 
FileOutputStream os = new FileOutputStream(FILEORIGINAL);
InputStream ip = acrofields.extractRevision(signatureName);
int n = 0;
byte bb[] = new byte[1028];
while ((n = ip.read(bb)) > 0)
    os.write(bb, 0, n);
os.close();
ip.close();
reader.close();

但是提取出来的pdf和原来的不一样。 我会在签名前提取修订版吗?可能吗?

感谢您的帮助。 萨拉

I want to extract the original pdf to compare its hash with that of the unsigned pdf.

一般来说这是不可能的。

当 iText(或其他 PDF 签名库或应用程序)签署 PDF 时,它们:

  1. 向 PDF 添加签名表单域(除非存在空的签名表单域并被选择用于签名);
  2. 向 PDF 添加一个字典对象,其中包含一些与签名相关的条目,特别是一个大的占位符条目,最终将在其中插入 CMS 签名容器;此字典设置为上述表单字段的值;
  3. 向表单字段添加可视化,通常包含来自签名者证书的一些数据(除非签名被选择为不可见);
  4. 如果为带有字段锁定信息的字段签名为空,则将其他一些表单字段设置为只读;
  5. 完成 PDF,即他们设置元数据,如上次更改时间,然后将完成的 PDF 写入文件或某个字节数组;
  6. 计算完成的 PDF 的哈希值,不包括大占位符的值,但包括如上所述所做的所有其他更改;
  7. 对该散列值进行签名,生成 CMS 签名容器;
  8. 并将这个签名容器放入大占位符中。

因此,一般来说 "original pdf" 不能再从已签名的 PDF 文件中提取出来,因为上述更改可能从根本上改变了 PDF 的内部结构。

不过有一个例外:如果这些更改作为增量更新应用(在 iText 行话中:追加模式) , 通常可以通过切断增量更新来检索原始文件。

对于这个只需要在签名之前搜索最新的文件结束标记,然后将其切断即可。 (实际上存在少量不安全因素,最终的行尾标记可能是也可能不是原始 PDF 的一部分。)