在Itext 7中,如何获得范围流来签署pdf?

时间:2016-08-10 09:25:58

标签: java itext digital-signature itext7

我正在尝试将我的应用程序从iText 5.5.9迁移到iText 7,并且我在使用客户端上创建的签名(在PDF文档的数字签名中描述)在服务器上签署文档时遇到问题。

由于getRangeStream()方法不再公开,因为它在iText 5.5.9中,我怎样才能获得对范围流的引用?

1 个答案:

答案 0 :(得分:3)

getRangeStream不是唯一一种从PdfSignatureAppearance重构为PdfSigner并以protected方式重构的方法。其他方法也存在同样的问题,例如preCloseclose,它们也是来自 PDF文档的数字签名的PreSignPostSign servlet中使用的方法您似乎使用或至少借用了代码。

正如我所说,这已经完成,使iText 7用户使用signDeferredsignDetachedsignExternalContainer方法,这些方法通常足以签署应用程序并“正确执行“,即以创建有效签名的方式使用另一个,现在不再使用公共方法。

遗憾的是,PreSignPostSign servlet不能使用这三种方法,它们实际上就像signDetached代码被分成两半,相关的局部变量存储在HTTP中会话。

因此,您基本上有两个选择:

尽管使用受保护的方法

除非我忽略了某些内容,否则甚至可以通过从PdfSigner派生自己的签名者类并使这些方法和可能的成员变量再次公开访问来完成;乍一看使用反射魔法似乎没有必要。

更改PreSignPostSign servlet架构

如果您可以从保留内存中的签名相关对象(通过HTTP会话引用)切换到仅将中间PDF文件保存在内存中,甚至保存在磁盘上,并且可能是内存中的半生不熟的签名容器,您可以继续这样:

  • PreSign servlet替换为使用PdfSigner.signExternalContainer使用IExternalSignatureContainer实现“签名”PDF的servlet,该实现只提供虚拟签名,例如: new byte[0]

    IExternalSignatureContainer检索所寻找的范围流作为其sign方法的参数,因此它可以计算范围流哈希值。

    现在,带有虚拟签名的PDF可以保存到磁盘或保存在内存中。并且基于范围流哈希,您可以像以前一样继续构建和提供PdfPKCS7实例。并将其保存在内存中,例如从HTTP会话引用。

  • 用一个servlet替换PostSign servlet,这个servlet在完成PdfPKCS7实例的提供之前生成一个CMS签名容器。然后使用PdfSigner.signDeferred方法将此容器注入已保存的PDF中。

或者,您甚至可以将整个CMS签名容器创建移动到客户端。在这种情况下,所有会话都必须记住存储中间PDF的位置......

一些灵感可能来自C4_09_DeferredSigning.java iText 7示例。