当前位置: 首页 > 知识库问答 >
问题:

PDF签名无效,但带有PDFBox2的Verfiy签名有效(true)

祖新觉
2023-03-14

PDF下载示例:https://drive.google.com/file/d/12wv1Pb7gh4vCKOGhX4cZ3aOrLSiOo4If/view?usp=sharing

因此,当PDF在A.Reader(连续版本)中打开时,它表示证书无效,因为对该文档所做的更改导致签名无效。

但我看不出有什么变化。我们自己的应用程序只添加了一个签名(证书),为数千个其他PDF添加了正确的签名。未执行其他更改。使用我们自己的代码验证散列,或者使用PDFBox2和以下代码验证散列,则表示签名有效(true)。

那么为什么读者会抱怨呢?

非常感谢您的帮助,因为我已经有好几天的时间了。。。

public static void main(String [] args) throws IOException, CMSException, OperatorCreationException, CertificateException
{
    System.out.println("\nValidate signature in SignatureVlidationTest.pdf; original code.");
    byte[] pdfByte;
    PDDocument pdfDoc = null;
    SignerInformationVerifier verifier = null;
    try
    {
        pdfByte = FileUtils.readFileToByteArray(new File(FOLDEROUT, "102089-5913E701-5EE6-AC3F-7B03-A8D27A7CD9FA.pdf"));  
        pdfDoc = PDDocument.load(new File(FOLDEROUT, "102089-5913E701-5EE6-AC3F-7B03-A8D27A7CD9FA.pdf"));  
       // pdfDoc = Loader.loadPDF(new ByteArrayInputStream(pdfByte));
        PDSignature signature = pdfDoc.getSignatureDictionaries().get(0);

        byte[] signatureAsBytes = signature.getContents();
        byte[] signedContentAsBytes = signature.getSignedContent(pdfByte);
        CMSSignedData cms = new CMSSignedData(new CMSProcessableByteArray(signedContentAsBytes), signatureAsBytes);
        SignerInformation signerInfo = (SignerInformation) cms.getSignerInfos().getSigners().iterator().next();
        X509CertificateHolder cert = (X509CertificateHolder) cms.getCertificates().getMatches(signerInfo.getSID())
                .iterator().next();
        verifier = new JcaSimpleSignerInfoVerifierBuilder().setProvider(new BouncyCastleProvider()).build(cert);

        // result if false
        boolean verifyRt = signerInfo.verify(verifier);
        System.out.println("Verify result: " + verifyRt);
    }
    finally
    {
        if (pdfDoc != null)
        {
            pdfDoc.close();
        }
    }
}

共有1个答案

周阳成
2023-03-14

第一个修订版末尾的交叉引用表如下所示:

xref
0 19
0000000000 65535 f
0000000018 00000 n
0000000348 00000 n
0000000422 00000 n
0000000481 00000 n
0000000776 00000 n
0000003138 00000 n
0000032630 00000 n
0000033308 00000 n
0000033489 00000 n
0000033723 00000 n
0000033932 00000 n
0000056202 00000 n
0000056645 00000 n
0000056837 00000 n
0000070988 00000 n
0000071312 00000 n
0000071521 00000 n
0000071543 00000 n
20 26
0000071844 00000 n
0000080069 00000 n
0000080373 00000 n
0000080556 00000 n
0000097791 00000 n
0000097813 00000 n
0000097833 00000 n
0000097853 00000 n
0000097876 00000 n
0000097899 00000 n
0000097922 00000 n
0000097945 00000 n
0000097968 00000 n
0000097991 00000 n
0000098014 00000 n
0000098037 00000 n
0000098059 00000 n
0000098083 00000 n
0000104407 00000 n
0000104444 00000 n
0000104483 00000 n
0000104565 00000 n
0000104704 00000 n
0000104728 00000 n
0000111035 00000 n
0000111072 00000 n
48 1
0000111098 00000 n
50 2
0000111296 00000 n
0000113066 00000 n

如您所见,它由多个子部分组成,对象编号为0。。18, 20..45、48和50。。尤其是,没有对象编号19、46、47和49的映射。

这是不允许的,原因有两个:

>

交叉引用表(包括原始交叉引用部分和所有更新部分)应包含从0到文件中定义的最大对象编号的每个对象编号的一个条目,即使该范围内的一个或多个对象编号不实际出现在文件中。

(ISO 32000-1第7.5.4节“交叉参考表”)

因此,常规PDF的第一个交叉引用表必须只包含一个小节。即使不需要,也不允许有未映射对象编号的间隙。

通常,Adobe Reader会忽略违反这些要求的行为,但在签名验证方面,它更为严格。通常,这种情况会出现在对所讨论的PDF进行签名,然后添加一些任意增量更新的情况下。

例如,我获取了您的第一个修订版(文件的前114510个字节)并对它们进行了签名,然后将它们扩展为LTA:

 类似资料:
  • 作为我对客户机/服务器pdf签名研究的一部分,我测试了itext pdf延迟签名示例。不幸的是,我得到的合并空签名pdf和哈希值的pdf ie输出显示无效签名。 下面是我的代码片段 我正在使用pkcss11 usb令牌进行签名

  • 我找不到为什么Foxit PDF阅读器显示我的签名文件无效。首先,我将空白签名容器插入pdf 我发送到外部Web服务以使用合格的签名进行签名。 接下来,我使用webservice的结果对pdf进行了签名。这是外部签名容器: 这是签名代码: 并且有结果: 找不到我做错了什么。

  • 当我使用带电子令牌的IText对PDF进行签名时,签名的PDF在Acrobat Adobe Reader中显示“至少一个签名无效”。我正在使用有效的电子代币。以下是签署Pdf的代码。

  • 我正在使用瑞士电信数字签名服务,我们有一个测试帐户。服务需要散列码pdf文件。我们把它和 数字签名(PKCS#7-延迟签名)/自应用签名以来文档已被更改或损坏 我的回应是sha256被加密了。我正在使用iText和C#来签署pdf文件。我签字,我看到一些细节(如原因,地点等)。 下面是创建带有签名字段的pdf文件的方法 我错过了什么或者做错了什么?

  • 我对iTextSharp有意见。我有一个带有表单字段的文档,并且我已经为签名生成了字段。当第一个人在文件上签字时,它就会正常工作。Adobe Reader显示有效签名。当我让第二个人在文档上签名时,Adobe Reader显示签名1现在是“未知签名”,签名无效。Adobe reader显示: 此签名中包含的格式或信息有错误(支持信息:SigDict/Contents非法数据)

  • 我在PDF文档中(以编程方式)填写一个表单(AcroPdf),然后在文档上签名。我从doc.pdf开始,使用pdfbox的setfields.java示例创建doc_filler.pdf。然后我对doc_fill.pdf进行签名,创建doc?filled_signer.pdf,使用一些代码,基于签名示例并在Acrobat Reader中打开pdf。输入的字段数据是可见的,并且签名面板告诉我 “此签