我正在尝试将我的应用程序从 iText 5.5.9 迁移到 iText 7,并且在使用客户端上创建的签名(在 PDF 文档的数字签名中描述)对服务器上的文档进行签名时遇到问题。
由于该getRangeStream()
方法不再像在 iText 5.5.9 中那样公开,我如何获得对范围流的引用?
我正在尝试将我的应用程序从 iText 5.5.9 迁移到 iText 7,并且在使用客户端上创建的签名(在 PDF 文档的数字签名中描述)对服务器上的文档进行签名时遇到问题。
由于该getRangeStream()
方法不再像在 iText 5.5.9 中那样公开,我如何获得对范围流的引用?
getRangeStream
不是唯一从PdfSignatureAppearance
to重构PdfSigner
并以protected
这种方式制作的方法。其他方法也存在同样的问题,例如preClose
和close
也是用于 PDF 文档的数字签名PreSign
和PostSign
servlet 的方法,您似乎使用或至少从中借用代码。
正如我所推测的那样,这样做是为了让 iText 7 用户使用通常足以签署应用程序并“正确执行”的方法signDeferred
,即使用其他的、现在不再是公共方法的方法来创建有效的签名。signDetached
signExternalContainer
不幸的是,servletPreSign
和PostSign
servlet 不能使用这三种方法,它们实际上就像signDetached
被撕成两半的代码,相关的局部变量存储在 HTTP 会话中。
因此,您基本上有两种选择:
除非我忽略了某些事情,否则这甚至可以通过派生您自己的签名者类PdfSigner
并使这些方法和可能的成员变量再次可公开访问来完成;乍一看似乎没有必要使用反射魔法。
PreSign
和PostSign
servlet 架构如果您可以从将那些与签名相关的对象保存在内存中(通过 HTTP 会话引用)切换到仅将中间 PDF 文件保存在内存中甚至磁盘上,并且可能将半生不熟的签名容器保存在内存中,则可以这样进行:
将PreSign
servlet 替换为使用仅提供虚拟签名PdfSigner.signExternalContainer
的实现“签名”PDF 的 servlet,例如.IExternalSignatureContainer
new byte[0]
这将IExternalSignatureContainer
检索寻找的范围流作为其sign
方法的参数,因此它可以计算范围流哈希。
现在可以将带有虚拟签名的 PDF 保存到磁盘或保存在内存中。并且基于范围流哈希,您可以PdfPKCS7
像以前一样继续构建和提供实例。并将其保存在内存中,例如从 HTTP 会话中引用。
用一个 servlet替换PostSign
servlet,该 servlet 像以前一样完成输入PdfPKCS7
实例并生成 CMS 签名容器。然后使用该方法将此容器注入到保存的 PDF 中PdfSigner.signDeferred
。
或者,您甚至可以将整个 CMS 签名容器创建移动到客户端。在这种情况下,所有会话必须记住的是中间 PDF 的存储位置......
一些灵感可能来自C4_09_DeferredSigning.java iText 7 示例。