我正在尝试执行以下设置来签署pdf,分解为客户端和服务器之间的异步步骤:
第二个问题允许我编写大部分代码,但是我发现文件的完整性已经被破坏了。我似乎无法序列化中间pdf以便稍后嵌入签名(以确保没有时间戳被更改等)。但从第一个问题来看,它似乎比我想象的更难。真的可以吗?
我正在使用pdfbox。
服务器代码:
ExternalSigningSupport externalSigning = document.saveIncrementalForExternalSigning(fos);
externalSigning.setSignature(encodedSignature); // encodedSignature is received from client and computed based on the digest sent by the server
我基本上做的是将该摘要发送给客户端进行签名,然后在服务器上重做上述步骤并设置客户端签名:
encodedSignature
此设置最终导致文件的完整性被破坏,因为我在服务器上安装了{{1}}后创建了一个新的PDSignature来嵌入它。有没有办法序列化调用addSignature后创建的PDDocument,所以我以后可以在服务器上反序列化它并添加客户端的签名?
答案 0 :(得分:2)
What I'm basically doing is sending that digest to the client to sign and then on the server redoing the above steps and setting the client signature
If you want those above steps to generate identical documents, you need to
If you do so, the outputs of the above steps are identical as is required for your task.
One step of your above steps is prone to result in different inputs:
Calendar date = Calendar.getInstance();
signature.setSignDate(date);
To guarantee identical inputs, you have to determine date
only once and use that single value every time you execute those steps for the same signing transaction.
As recommended by the specification, PDFBox attempts to give each PDF revision its unique ID. In the case at hand, though, we need the same revision ID both times the above steps are executed.
Fortunately, PDFBox allows us to provide the seed value it uses to make the revision ID unique enough.
As we don't want to same revision ID all the time we sign the same document but merely during the current signing transaction, we should use the same seed value only in the same transaction. As the seed value is a long, we can simply use the time in milliseconds corresponding to the date
already discussed above, i.e.:
pdDocument.setDocumentId(date.getTimeInMillis());