我正在尝试将我的应用程序从iText 5.5.9迁移到iText 7,并且我在使用客户端上创建的签名(在PDF文档的数字签名中描述)在服务器上签署文档时遇到问题。
由于getRangeStream()
方法不再公开,因为它在iText 5.5.9中,我怎样才能获得对范围流的引用?
答案 0 :(得分:3)
getRangeStream
不是唯一一种从PdfSignatureAppearance
重构为PdfSigner
并以protected
方式重构的方法。其他方法也存在同样的问题,例如preClose
和close
,它们也是来自 PDF文档的数字签名的PreSign
和PostSign
servlet中使用的方法您似乎使用或至少借用了代码。
正如我所说,这已经完成,使iText 7用户使用signDeferred
,signDetached
和signExternalContainer
方法,这些方法通常足以签署应用程序并“正确执行“,即以创建有效签名的方式使用另一个,现在不再使用公共方法。
遗憾的是,PreSign
和PostSign
servlet不能使用这三种方法,它们实际上就像signDetached
代码被分成两半,相关的局部变量存储在HTTP中会话。
因此,您基本上有两个选择:
除非我忽略了某些内容,否则甚至可以通过从PdfSigner
派生自己的签名者类并使这些方法和可能的成员变量再次公开访问来完成;乍一看使用反射魔法似乎没有必要。
PreSign
和PostSign
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示例。