iText验证Java中pdf的完整性 [英] iText verify integrity of a pdf in java

查看:939
本文介绍了iText验证Java中pdf的完整性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Web服务器生成一个pdf,对其进行签名,然后将其提供给客户端.客户端多次签名(使用Adobe Pro使用不同的令牌),然后将其上传回服务器.

My web server generates a pdf, signs it, and give it to the client. The client sign it multiple times (with different tokens using Adobe Pro) and then upload it back to the server.

我希望服务器验证它是否是服务器先前生成的pdf.我读到,应用多个签名时,哈希值发生了变化.如何使用iText轻松进行此验证?

I want the server to verify if it is the pdf that was previously generated by the server. I read that the hash is changed when multiple signatures are applied. How can do this verification easily with iText ?

推荐答案

如果正确完成,则通过增量更新应用同一PDF中的多个集成签名.在信息安全堆栈交换上此答案:

Multiple integrated signatures in the same PDF are applied by means of incremental updates if done properly, cf. this answer on Information Security Stack Exchange:

因此,从某种程度上来说,您阅读的内容是真实的

Thus, while in a way it is true what you read

我了解到,应用多个签名时,哈希值发生了变化.

I read that the hash is changed when multiple signatures are applied.

(实际上,除非有非常不可能的冲突,否则整个文件的哈希会发生变化),您的初始签名适用的字节字节的哈希仍然存在,并且可以是从文档中检索.

(indeed, the hash of the whole file changes unless you have an extremely unlikely collision), the hash of the bytes your initial signature applies to remains and can be retrieved from the document.

因此,根据您要检查的内容以及您仍然拥有的信息,有以下明显的选择:

So depending on what you want to check and what information you still have, there are these obvious options:

我的Web服务器生成一个pdf文件,对其进行签名,然后将其提供给客户端

My web server generates a pdf, signs it, and give it to the client

如果您仍将初始签名的PDF存储在某个地方(例如,在数据库中),并且要检查客户端上传回给您的PDF是否基于该PDF,那么您要做的就是检查客户端的PDF字节流从您存储的PDF字节开始.

If you still have that initial signed PDF stored somewhere (e.g. in a database) and you want to check whether the PDF the client uploaded back to you is based on that very PDF, all you need to do is check whether the client's PDF byte stream starts with the bytes of the PDF you stored.

这不需要额外使用加密功能或PDF特定的API,只需比较它们的字节或块即可.

This does not require any extra use of cryptographic functions or PDF specific APIs, merely a comparison of bytes or blocks of them.

我的Web服务器生成一个pdf文件,对其进行签名,然后将其提供给客户端

My web server generates a pdf, signs it, and give it to the client

如果您没有在任何地方存储初始签名的PDF,或者仅想检查客户端上传回您的PDF是否基于您签名的许多基本PDF之一,则不可能进行直接修订比较,或者非常简单.资源密集型.

If you don't have that initial signed PDF stored anywhere or you only want to check whether the PDF the client uploaded back to you is based on one of many possible base PDFs signed by you, direct revision comparison is impossible or very resource intensive.

在这种情况下,您应该检查文档的初始签名

In this case you should check whether the initial signature of the document

  • 有效且
  • 已由您的服务器创建.

关于如何检查PDF签名完整性的例子很多,例如

There are many examples on how to check the integrity of signatures in a PDF, e.g.

public PdfPKCS7 verifySignature(AcroFields fields, String name) throws GeneralSecurityException, IOException {
    System.out.println("Signature covers whole document: " + fields.signatureCoversWholeDocument(name));
    System.out.println("Document revision: " + fields.getRevision(name) + " of " + fields.getTotalRevisions());
    PdfPKCS7 pkcs7 = fields.verifySignature(name);
    System.out.println("Integrity check OK? " + pkcs7.verify());
    return pkcs7;
}

public void verifySignatures(String path) throws IOException, GeneralSecurityException {
    System.out.println(path);
    PdfReader reader = new PdfReader(path);
    AcroFields fields = reader.getAcroFields();
    ArrayList<String> names = fields.getSignatureNames();
    for (String name : names) {
        System.out.println("===== " + name + " =====");
        verifySignature(fields, name);
    }
    System.out.println();
}

(对于您的任务,您实际上可以仅将自己限制为仅检查第一个签名,但是也可以检查其他签名,这也是一个好主意.

For your task you actually can simply restrict yourself to checking the first signature only but checking the other ones, too, might also be a good idea.

要检查服务器是否已创建初始签名,我们假设您的Web服务器使用专用于此任务的X509证书(或已知的此类证书)对这些PDF进行签名.

To check whether the initial signature has been created by your server, let's assume your web server signs these PDFs using a X509 certificate dedicated to this task (or a known set of such certificates).

您可以使用从verifySignature调用中获取的第一个签名的PdfPKCS7对象的方法getSigningCertificate来检索用于创建初始签名的证书.您要做的就是检查证书是否是您专用于此任务的一个证书(或一组证书中的一个).

You can retrieve the certificate using which the initial signature was created with the method getSigningCertificate of the PdfPKCS7 object you retrieve from the verifySignature call for the first signature. All you have to do is check whether the certificate is the one certificate (or one of the set of certificates) you dedicated for this task.

这篇关于iText验证Java中pdf的完整性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆