获取使用itextsharp签名的pdf的原始内容

时间:2013-04-09 09:18:52

标签: .net pdf itextsharp itext digital-signature

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

当文档有多个签名时,这非常简单,使用acrobat reader可以将文档的上一版本保存,就可以了。

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

由于无法用读取器执行此操作,因此我尝试使用iTextSharp进行编程。然而,虽然我已经深入搜索,但我还没有找到如何做到这一点。我找到的唯一相关帖子是one,但没有提供解决方案。

是否有人遇到此问题并找到了解决方案?

提前致谢。

编辑:我在这里放了根据mkl的响应提取数据的代码。阅读响应的注释,注意未签名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);

1 个答案:

答案 0 :(得分:4)

您的任务是否可以实现签名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. 如果签名追加模式中应用,则表示运气不佳:处理PDF的程序(例如用于签名)可能会完全重新排列二进制内容您的文档,甚至可能重新编号对象,更改压缩,删除未使用的对象等,而文档的外观保持不变。