Java 使用摘要对pdf进行异步签名
我正在尝试执行以下PDF签名设置,在客户端和服务器之间分为异步步骤:Java 使用摘要对pdf进行异步签名,java,pdf,pdfbox,pkcs#7,Java,Pdf,Pdfbox,Pkcs#7,我正在尝试执行以下PDF签名设置,在客户端和服务器之间分为异步步骤: 服务器接收pdf并计算其摘要 服务器将摘要发送到客户端 客户端稍后对哈希进行签名 客户端将签名发送到服务器 服务器将签名嵌入到pdf中 我的立足点主要在和 第二个问题允许我编写大部分代码,但是我发现文件的完整性受到了破坏。我似乎无法序列化中间pdf以便稍后嵌入签名(以确保没有时间戳被更改,等等)。但从第一个问题开始,这似乎是一个比我想象的更难的问题。这真的能做到吗 我用的是pdfbox 服务器代码: PDDoc
PDDocument document = PDDocument.load(documentFile);
PDSignature signature = new PDSignature();
signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
signature.setName("Example User");
signature.setLocation("Los Angeles, CA");
signature.setReason("Testing");
Calendar date = Calendar.getInstance();
signature.setSignDate(date);
document.addSignature(signature);
ExternalSigningSupport externalSigningSupport = document.saveIncrementalForExternalSigning(null);
byte[] content = IOUtils.toByteArray(externalSigningSupport.getContent());
MessageDigest md = MessageDigest.getInstance("SHA256", new BouncyCastleProvider());
byte[] digest = md.digest(content); // this is sent to client
我所做的基本工作是将摘要发送到客户端进行签名,然后在服务器上重新执行上述步骤并设置客户端签名:
ExternalSigningSupport externalSigning = document.saveIncrementalForExternalSigning(fos);
externalSigning.setSignature(encodedSignature); // encodedSignature is received from client and computed based on the digest sent by the server
这个设置最终导致文件的完整性被破坏,因为一旦我在服务器上嵌入了encodedSignature
,我就会创建一个新的PDSignature。是否有办法序列化调用addSignature后创建的PDDocument,以便稍后在服务器上对其进行反序列化并添加客户端的签名
我所做的基本工作是将摘要发送给客户端进行签名,然后在服务器上重新执行上述步骤并设置客户端签名
如果希望上述步骤生成相同的文档,则需要
- 确保这些步骤的输入相同且正确
- 提供相同的修订id种子值
Calendar date = Calendar.getInstance();
signature.setSignDate(date);
为了保证输入相同,您必须仅确定一次日期
,并在每次为同一签名事务执行这些步骤时使用该单一值
提供相同的修订id种子值
按照规范的建议,PDFBox尝试为每个PDF版本提供其唯一的ID。不过,在本例中,执行上述步骤时,我们需要相同的版本ID
幸运的是,PDFBox允许我们提供它用来使修订ID足够唯一的种子值
由于我们不希望在签署同一文档时始终使用相同的修订ID,而只是在当前签名事务中,因此我们应该仅在同一事务中使用相同的种子值。由于种子值很长,我们可以简单地使用与上面讨论的日期
对应的时间(以毫秒为单位),即:
pdDocument.setDocumentId(date.getTimeInMillis());
我只是有时间来试试这个。我发现:无法写入签名,org.apache.pdfbox.pdfwriter.COSWriter.writeExternalSignature(COSWriter.java:789)的空间不足。我通过之前为签名分配空间来解决这个问题,但这是一种与此初始技术非常不同的方法。“这是一种与此初始技术非常不同的方法。”-实际上,这并没有改变太多原始方式,只需使用
document.addSignature(签名,选项)
而不是文档。添加签名(签名)
<这里的代码>选项需要是一个SignatureOptions`实例,在该实例中,您将PreferredSignatureSize设置为足够高的值……您有完整的示例吗?