在Itext 7中,如何获取范围流来签署pdf? [英] In Itext 7, how to get the range stream to sign a pdf?
问题描述
我正在尝试将我的应用程序从iText 5.5.9迁移到iText 7,并且我在使用客户端上创建的签名(在PDF文档的数字签名中描述)在服务器上签署文档时遇到问题。
I'm trying to migrate my application from iText 5.5.9 to iText 7 and I have a problem with signing a document on the server using a signature created on the client (described in the Digital Signatures for PDF documents).
由于 getRangeStream()
方法不再公开,因为它在iText 5.5.9中,怎么能我获得了对范围流的引用?
As the getRangeStream()
method isn't public anymore as it was in iText 5.5.9, how can I obtain a reference to the range stream?
推荐答案
getRangeStream
不是唯一的方法是从 PdfSignatureAppearance
重构为 PdfSigner
并使受保护
就这样。其他方法也存在同样的问题,例如 preClose
和 close
这些也是<$ c中使用的方法$ c> PreSign 和来自 PDF文档的数字签名的servlet,您似乎使用或至少借用代码来自。
getRangeStream
is not the only method that was refactored from PdfSignatureAppearance
to PdfSigner
and made protected
on that way. The same problem exists for other methods, too, like preClose
and close
which are also methods used in the PreSign
and PostSign
servlets from Digital Signatures for PDF documents which you seem to use or at least borrow code from.
据我所知,这已经完成,使iText 7用户使用 signDeferred
, signDetached
和 signExternalContainer
通常足以签署应用程序并正确执行的方法,即使用另一个,现在不是以某种方式创建有效签名的公共方法。
This, as I presume, has been done to make iText 7 users use the signDeferred
, signDetached
, and signExternalContainer
methods which usually are sufficient for signing applications and "do it correctly", i.e. use the other, now not anymore public methods in a way that creates valid signatures.
PreSign
和 PostSign
servlets因为遗憾的是它们不能使用这三种方法,它们实际上就像 signDetached
代码被分成两半,相关的局部变量存储在HTTP中会话。
The PreSign
and PostSign
servlets as they are unfortunately cannot use those three methods, they actually are like the signDetached
code ripped in two halves with the relevant local variables stored in the HTTP session.
因此,您基本上有两种选择:
Thus, you essentially have two choices:
除非我忽略了某些内容,否则甚至可以通过从 PdfSigner
派生自己的签名者类来完成。并使这些方法和可能的成员变量再次公开访问;似乎没有必要使用反射魔法。
Unless I overlooked something, this can even be done by deriving your own signer class from PdfSigner
and making those methods and probably member variables publicly accessibly again; using reflection magic at first sight doesn't seem necessary.
如果你可以从内存中保存那些签名相关对象(通过HTTP会话引用)切换到仅保留中间PDF文件在内存中甚至在磁盘上,可能是内存中的半成品签名容器,你可以这样继续:
If you could switch from keeping those signing related objects in memory (referenced via the HTTP session) to merely keeping an intermediary PDF file in memory or even on disk and probably the half-baked signature container in memory, you could proceed like this:
-
替换servlet使用
PdfSigner.signExternalContainer
使用签署PDF的
仅提供虚拟签名的实现,例如PreSign
servlet IExternalSignatureContainernew byte [0]
。
Replace the
PreSign
servlet by a servlet that "signs" the PDF usingPdfSigner.signExternalContainer
with aIExternalSignatureContainer
implementation that merely provides a dummy signature, e.g.new byte[0]
.
此 IExternalSignatureContainer
检索所寻求的范围流作为其 sign
方法的参数,因此它可以计算范围流哈希值。
This IExternalSignatureContainer
retrieves the sought-for range stream as parameter of its sign
method, so it can calculate the range stream hash.
现在,带有虚拟签名的PDF可以保存到磁盘或保存在内存中。并且基于范围流哈希,您可以像以前一样继续构建和提供 PdfPKCS7
实例。并将其保存在内存中,例如从HTTP会话引用。
Now the PDF with the dummy signature can be saved to disk or held in memory. And based on the range stream hash you can continue constructing and feeding the PdfPKCS7
instance as before. And hold that in memory, e.g. referenced from the HTTP session.
用servlet替换 PostSign
servlet,如同以前完成提供 PdfPKCS7
实例并生成CMS签名容器。然后使用 PdfSigner.signDeferred
方法将此容器注入已保存的PDF中。
Replace the PostSign
servlet by a servlet that as before finishes feeding the PdfPKCS7
instance and generates a CMS signature container. Then inject this container into the saved PDF using the PdfSigner.signDeferred
method.
或者你甚至可以将整个CMS签名容器创建移动到客户端。在这种情况下,所有会话必须记住中间PDF存储的位置...
Alternatively you could even move the whole CMS signature container creation to the client. In that case all the session has to remember is where the intermediary PDF is stored...
一些灵感可能来自 C4_09_DeferredSigning.java iText 7示例。
Some inspiration may come from the C4_09_DeferredSigning.java iText 7 example.
这篇关于在Itext 7中,如何获取范围流来签署pdf?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!