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

Java 使用Itext验证Pdf签名时出现意外结果,java,validation,pdf,digital-signature,integrity,Java,Validation,Pdf,Digital Signature,Integrity,我正在尝试用Itext 5.4和BouncyCastle 1.49验证PDF签名(通过AdobeReader X手动使用我的数字证书进行签名) 但是验证结果总是出乎意料的,下面是我的Java代码: **Security.addProvider(new BouncyCastleProvider()); PdfReader reader = new PdfReader("E:/signTest.pdf"); AcroFields acro = reader.getAcroFields()

我正在尝试用Itext 5.4和BouncyCastle 1.49验证PDF签名(通过AdobeReader 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”文档。预期结果应该是:完整性检查正常吗?错误

有人曾经解决过这个问题吗

如果您有任何建议。

“完整性检查正常”(由于
pkcs7.verify()。如果您在附加模式(也称为增量更新)中应用了更改,则不会触及最初签名的字节范围

如果要检查更改是否已作为增量更新进行,请检查
acro.SignatureOverwholeDocument(“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

关于你的评论

我遵照您的建议,在检查整个签名文档(“签名字段”)时得到“假”返回。那么这是否意味着“未触及原始有符号字节范围”

<>你必须考虑那些结果值的组合:

  • pkcs7.verify()
    指示指示的签名本身在内部是否正常,是否正确地对相关签名字典中指示的字节范围进行签名

  • acro.SignatureOverwholeDocument(“signatureField”)
    表示由指定签名签名的字节范围是否覆盖整个文档(显然,签名本身除外)

只有当两个结果均为
true
时,签名才会得到肯定验证,以在文档的当前状态下签名

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

与Adobe Reader等不同,iText还不能检查内容的更改类型。因此,它无法告诉您这些更改是允许的还是不允许的

如果前一个为false,则无法再提取签名最初正确签名的状态(如果曾经存在这种状态)

那么我怎样才能将签名应用于整个文件

签署PDF时,签名覆盖整个文档。例如,示例文件
signTest\u after.pdf
中的签名确实涵盖了整个文件。填充字段之后在您的示例文件
signTest\u modified.pdf
中添加了一个新修订版,该修订版未包含在您的签名中

对于这方面的一些背景知识,您可能需要阅读以了解PDF签名的工作原理,了解PDF中的多个修订以及对已签名文档的允许和不允许更改的信息

对于使用iText和集成PDF签名,您可能需要学习Bruno Lowagie(iText软件)的白皮书,特别是第5章签名文档的验证。

“完整性检查正常”(由于
pkcs7.verify()
)只会告诉您最初签名的版本,PDF的原始有符号字节范围尚未更改。如果您在附加模式(也称为增量更新)中应用了更改,则不会触及最初签名的字节范围

如果要检查更改是否已作为增量更新进行,请检查
acro.SignatureOverwholeDocument(“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

关于你的评论

我遵照您的建议,在检查整个签名文档(“签名字段”)时得到“假”返回。那么这是否意味着“未触及原始有符号字节范围”

<>你必须考虑那些结果值的组合:

  • pkcs7.verify()
    指示指示的签名本身在内部是否正常,是否正确地对相关签名字典中指示的字节范围进行签名

  • acro.SignatureOverwholeDocument(“signatureField”)
    表示由指定签名签名的字节范围是否覆盖整个文档(显然,签名本身除外)

只有当两个结果均为
true
时,签名才会得到肯定验证,以在文档的当前状态下签名

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

与Adobe Reader等不同,iText还不能检查内容的更改类型。因此,它无法告诉您这些更改是允许的还是不允许的

如果前一个为false,则无法再提取签名最初正确签名的状态(如果曾经存在这种状态)

那么我怎样才能将签名应用于整个文件

签署PDF时,签名覆盖整个文档。例如,示例文件
signTest\u after.pdf
中的签名确实涵盖了整个文件。填充字段之后在您的示例文件
signTest\u modified.pdf
中添加了一个新修订版,该修订版未包含在您的签名中

对于这方面的一些背景,您可能希望阅读以了解PDF签名是如何工作的,以了解有关多版本的信息