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