【问题标题】:get original content of a pdf signed with itextsharp获取使用 itextsharp 签名的 pdf 的原始内容
【发布时间】:2013-03-31 15:42:24
【问题描述】:

我正在尝试获取签名 PDF 的原始文档,以便将其哈希值与存储的文档进行比较。

当文档有多个签名时,这真的很容易,使用 acrobat reader 你可以去文档的上一个版本保存它,就是这样。

令人惊讶的是,这不适用于第一个签名,因为没有直接的方法来获取原始数据。

由于无法通过阅读器来完成,我已尝试使用 iTextSharp 以编程方式进行操作。但是,尽管我已经深入搜索,但我还没有找到如何做到这一点。我找到的唯一相关帖子是 one,但没有提供解决方案。

有没有人遇到过这个问题并找到了解决方案?

提前致谢。

编辑:我将根据 mkl 的响应提取数据的代码放在这里。阅读响应的 cmets 以提防未签名 PDF 长度不固定的问题。

String sOriginalText = File.ReadAllText("FileSigned.pdf", Encoding.Default);
int sTrailerNumberPosition = sOriginalText.LastIndexOf("]/Prev ") + "]/Prev ".Length;
int sTrailerNumberEndPosition = sOriginalText.IndexOf(">", sTrailerNumberPosition);
String sTrailerIndex = sOriginalText.Substring(sTrailerNumberPosition, sTrailerNumberEndPosition -sTrailerNumberPosition);
int iTrailerIndexPosition = sOriginalText.IndexOf(sTrailerIndex + "\r\n%%EOF");
int iEndPosition = sOriginalText.IndexOf("%%EOF", iTrailerIndexPosition) + "%%EOF".Length;
String sOutText = sOriginalText.Substring(0, iEndPosition);
File.WriteAllText("c:/OriginalFile.pdf", sOutText, Encoding.Default);

【问题讨论】:

    标签: .net pdf itextsharp itext digital-signature


    【解决方案1】:

    您的任务获取已签名 PDF 的原始文档是否完全可以实现,取决于最初应用签名的方式。

    1. 如果签名是在 追加 模式下应用的(即根据 PDF 规范 ISO 32000-1:2008 的语言作为增量更新,参见第 7.5.6 节) ,您只需切断这个附加的增量更新修订。

      由于您有一个存储的文档,可能在签名后已成为您检查的文档,您可以简单地将已签名的文件剪切为存储文件的长度并进行比较,例如使用哈希。这足以表明签名的文档来自您的原始文档。不过,可能还有其他中间修订,因为您可能只是切断了多个增量更新。

      一般情况下,您可以按照已签名 PDF 的 /Prev 预告片条目到先前修订版的交叉引用表中找到先前修订版,然后从那里移动到文档结束标记 %%EOF 因为在增量更新中

      添加的预告片应包含除前一个预告片中的 Prev 条目(如果存在)之外的所有条目,无论是否修改。此外,添加的尾部字典应包含一个 Prev 条目,给出前一个交叉引用部分的位置(参见表 15)。每个预告片应由其自己的文件结束 (%%EOF) 标记终止。

      如果 PDF 使用交叉引用流而不是交叉引用表,则交叉引用流字典中有类似的条目:

      (仅在文件具有多个交叉引用流时出现;在混合引用文件中没有意义;参见 7.5.8.4,“与不支持压缩引用流的应用程序的兼容性”)解码后的字节偏移量从文件的开头流到前一个交叉引用流的开头。该条目与预告片字典中的 Prev 条目具有相同的功能(表 15)。

      不过,您应该知道,附加的增量更新修订版可以包含除签名之外的其他更改。因此,即使先前的修订与您存储的文档相对应,您仍然只知道签名的文档是基于您保存的文档。

    2. 如果在 append 模式下应用签名,那么您就不走运了:处理 PDF 的程序(例如用于签名)可能会完全重新排列二进制内容您的文档,甚至可能重新编号对象,更改压缩,删除未使用的对象等,而文档的外观保持不变。

    【讨论】:

    • 非常感谢 mkl 的相关回答。我的签名处于附加模式,所以看起来我很幸运。 :) 我已经比较了 PDF 和超越比较,正如你所解释的,签名位于文件的最后一部分。您知道是否有任何方法可以使用 iText 以编程方式提取文件的最后一部分?还是我必须对其进行编码以检查 las Prev 指向的位置并从头开始剪切?
    • iText 仅允许提取已签名的修订。这种限制的一个原因是未完全确定未签名修订的结束。当您找到它的 %%EOF 标记后跟回车和换行时,您无法确定回车甚至换行是否属于旧版本。在您的情况下,您可以应用启发式方法,因为您有一个存储的文档,该文档是前体修订的候选者。
    • 再次感谢您的解释。实际上我没有原始文件,但它是散列。所以唯一的“问题”是知道 CR+LF 是否属于原件?在那种情况下,我可以计算带有和不带有 CR 和 CR+LF 的哈希值,并检查它们中的任何一个是否与存储的匹配。这种方法正确吗?
    • 如果你至少可以扩展你的数据存储以包含以前的文件大小会更好。问题在于,虽然根据标准,PDF 的最后一行必须包含 %%EOF 标记并且只有它,但野外有许多 PDF 后面有一些额外的垃圾字节。因此,这取决于原始文件遵循标准的严格程度。
    • 哇,好复杂。非常感谢所有这些细节。我会投票给你的答案,但我还没有足够的声誉:)
    猜你喜欢
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    • 2018-02-24
    • 1970-01-01
    相关资源
    最近更新 更多