【问题标题】:Get the original content from a signed pdf从签名的 pdf 中获取原始内容
【发布时间】:2015-04-13 11:25:45
【问题描述】:

我想知道如何使用 iText java 库或其他库从签名的 pdf 文档中获取原始内容。

谢谢

更新 1:

可能的例子:

PdfReader reader = new PdfReader(PATH_TO_PDF);
AcroFields fields = reader.getAcroFields();
ArrayList<String> signatures = fields.getSignatureNames();
for (String signature : signatures)
{
    // Start revision extraction
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    byte bb[] = new byte[8192];
    InputStream ip = fields.extractRevision(signature);
    int n = 0;
    while ((n = ip.read(bb)) > 0)
        out.write(bb, 0, n);
    out.close();
    ip.close();
    MessageDigest md = MessageDigest.getInstance("SHA1");
    byte[] resum = md.digest(out.toByteArray());
    // End revision extraction        
}

注意1:在这个例子中,当多个标志时,所有标志都实现了。

注2:但哈希值不等于原始哈希文档(未签名文档)

【问题讨论】:

  • 如果签名是以追加方式添加的,则很容易实现。在其他情况下这是不可能的。

标签: java itext signed


【解决方案1】:

请看下图:

在这种情况下,您有一个 PDF 文件(以 %PDF-1. 开头并以 %%EOF 结尾)并且数字签名是文档本身的一部分。它是签名字典中/Contents 键的值,即签名字段字典中/V 条目的值。

无法获得原来的 PDF,因为原始 PDF 已更改:对象已重新编号,添加了签名字段或 通过添加签名字典“填写”。

您可以删除签名,但这不会为您提供原始 PDF 文件。

PdfReader reader = new PdfReader(SIGNED); 
AcroFields acroFields = reader.getAcroFields(); 
acroFields.removeField("sig"); 
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(UNSIGNED)); 
stamper.close(); 
reader.close(); 

在这种情况下,SIGNED 是带有名为"sig" 的签名的文件的路径。我们删除完整的签名(包括签名字段)。结果文件的路径是UNSIGNED,并且该文件中不再有签名字段"sig" 的踪迹。这不再是已签名的原始 PDF。

现在看下图:

这显示了一个带有三个签名的 PDF。第一个签名是按照我之前描述的方式添加的:您无法再获取原始文档。

但是,第二个和第三个签名是以附加模式添加的。 这是添加额外签名的唯一方法,因为更改修订版 1 会破坏第一个签名。

如果您有修订版 3(标记为 Rev3),则很容易检索修订版 1 和 3(Rev1Rev2)。这显示在 Signatures 示例中:

PdfReader reader = new PdfReader(SIGNED);
AcroFields af = reader.getAcroFields();
FileOutputStream os = new FileOutputStream(REVISION);
byte bb[] = new byte[1028];
InputStream ip = af.extractRevision("first");
int n = 0;
while ((n = ip.read(bb)) > 0)
    os.write(bb, 0, n);
os.close();
ip.close();

在此示例中,"first" 是签名字段的名称,SIGNED 是带有签名的文件的路径,REVISION 是由此操作产生的修订的路径。

【讨论】:

  • 谢谢。所以如果我理解了你的解释,就无法实现原来的内容,因为第一个符号不是以追加模式添加的。
  • 其实我真正需要的是已经签名的原始文档的hash。有没有办法从签名的文件中实现它?谢谢
  • 不是原始文件;但是,您可以获得图像中蓝色部分的哈希值。如果无法获得已签名的原始哈希,则无法验证签名。为什么需要原始文档的哈希?为什么签名的哈希值不够?
  • @Eduardo 已签名的原始文档的哈希 - 请检查第一个签名是否已在附加模式下应用。许多签名服务都这样做。在这种情况下,您可以推断出原始 PDF(或至少几个可能是原始 PDF 的候选),因此,它的哈希值。
  • @BrunoLowagie 我想验证签名。我知道调用“fields.verifySignature(signame)”我正在验证签名,但我想检查该签名的哈希是否与我之前存储在数据库中的文档的哈希匹配
猜你喜欢
  • 2013-03-31
  • 1970-01-01
  • 2022-08-04
  • 1970-01-01
  • 2013-07-09
  • 1970-01-01
  • 2010-10-08
  • 1970-01-01
相关资源
最近更新 更多