使用Itext验证Pdf签名时出现意外结果

时间:2014-01-08 07:28:59

标签: java validation pdf digital-signature integrity

我正在尝试使用Itext 5.4和BouncyCastle 1.49验证PDF签名(通过Adobe Reader X使用我的数字证书手动签名)。

但验证结果总是出乎意料,这是我的Java代码:

  **Security.addProvider(new BouncyCastleProvider());
  PdfReader reader = new PdfReader("E:/signTest.pdf");
  AcroFields acro = reader.getAcroFields();
  PdfPKCS7 pkcs7 = acro.verifySignature("signatureField");
  System.out.println("Integrity check OK? " + pkcs7.verify());**

控制台显示:完整性检查确定?真

但请记住,我已修改了“signTest.pdf”文档。预期结果应为:完整性检查确定?假

有没有人必须解决这个问题?

我将不胜感激。

1 个答案:

答案 0 :(得分:2)

“完整性检查确定”(作为pkcs7.verify()的结果)仅告诉您最初签名的修订版本,PDF的原始签名字节范围尚未更改。如果您在追加模式中应用了更改,即使用增量更新,则不会触及最初签名的字节范围。

如果您想检查是否已将更改作为增量更新,请同时检查acro.signatureCoversWholeDocument("signatureField")

/**
 * Checks is the signature covers the entire document or just part of it.
 *
 * @param name the signature field name
 * @return <CODE>true</CODE> if the signature covers the entire document,
 * <CODE>false</CODE> otherwise
 */
public boolean signatureCoversWholeDocument(String name)

如果您确实更改了原始签名的字节范围,请在修改之前和之后提供PDF。

关于您的意见......

  

我按照你的建议在检查acro.signatureCoversWholeDocument(“signatureField”)时得到“false”返回。那么它是否意味着“未触及最初签名的字节范围”?

您必须考虑这些结果值的组合:

  • pkcs7.verify()表示指示的签名本身是否正常,并正确签署相关签名词典中指示的字节范围。

  • acro.signatureCoversWholeDocument("signatureField")表示由指示签名签名的字节范围是否覆盖整个文档(显然签名本身除外)。

仅当两个结果均为true时,才会对签名进行肯定验证,以便在当前状态下对文档进行签名。

如果前一个是true而后一个是false,则会对签名进行肯定验证以签署文档的前一个状态,该状态可以使用acro.extractRevision("signatureField")从文档中提取

与例如Adobe Reader,iText还不能检查内容的变化类型。因此,它无法告诉您更改是允许还是不允许

如果前一个是假的,那么签名最初确实签名的状态(如果有这样的状态)就不能被提取了。

  

然后我如何应用签名来覆盖整个文档?

签署PDF时,签名涵盖整个文档。例如。示例文件signTest_after.pdf中的签名确实涵盖了整个文件。之后填写字段会在您的示例文件signTest_modified.pdf中添加一个新的修订版本,但您的签名不在其中。

对于某些背景,您可能需要阅读this answer以了解PDF签名的工作原理,this answer了解PDF中的多个修订信息,以及{em>上的this answer允许和禁止更改签名文档。

一般情况下,对于使用iText和集成PDF签名,您可能需要学习Digital Signatures for PDF documents,Bruno Lowagie(iText软件)的白皮书,尤其是第5章签署文档的验证