getRangeStream不是从PdfSignatureAppearance重构为PdfSigner的唯一方法,并以此方式受到保护.其他方法也存在同样的问题,例如preClose和close,它们也是用于PDF文档的数字签名的PreSign和PostSign servlet中使用的方法,您似乎使用这些方法或者至少借用代码.
正如我所说,这已经完成,使iText 7用户使用signDeferred,signDetached和signExternalContainer方法,这些方法通常足以签署应用程序并“正确执行”,即使用另一种,现在不再使用公共方法了这会创建有效的签名.
不幸的是,PreSign和PostSign servlet不能使用这三种方法,它们实际上就像signDetached代码被分成两半,相关的局部变量存储在HTTP会话中.
因此,您基本上有两个选择:
尽管如此,请使用受保护的方法
除非我忽略了某些内容,否则甚至可以通过从PdfSigner派生自己的签名者类并使这些方法和可能的成员变量再次公开访问来完成;乍一看使用反射魔法似乎没有必要.
更改PreSign和PostSign servlet体系结构
如果您可以从保留内存中的签名相关对象(通过HTTP会话引用)切换到仅将中间PDF文件保存在内存中甚至磁盘上,并且可能是内存中的半成品签名容器,您可以这样继续:
>使用带有IfternalSignatureContainer实现的PdfSigner.signExternalContainer“签署”PDF的servlet替换PreSign servlet,该实现仅提供虚拟签名,例如:新字节[0].
此IExternalSignatureContainer检索所寻找的范围流作为其sign方法的参数,因此它可以计算范围流哈希.
现在,带有虚拟签名的PDF可以保存到磁盘或保存在内存中.并且基于范围流哈希,您可以像以前一样继续构建和提供PdfPKCS7实例.并将其保存在内存中,例如从HTTP会话引用.
>用一个servlet替换PostSign servlet,该servlet在完成PdfPKCS7实例的送入之前生成一个CMS签名容器.然后使用PdfSigner.signDeferred方法将此容器注入已保存的PDF.
或者,您甚至可以将整个CMS签名容器创建移动到客户端.在这种情况下,所有会话必须记住中间PDF存储的位置…