PDF 签名无效,但使用 PDFBox2 验证签名是否有效 (true)

PDF Signature invalid but Verify Signature with PDFBox2 is valid (true)

提问人:user1391606 提问时间:4/12/2023 更新时间:4/13/2023 访问量:76

问:

PDF 签名无效,但使用 PDFBox2 验证签名是否有效 (true)

样本PDF下载:

https://drive.google.com/file/d/18CY_6qe_xog9Zil0qNhF_o6h4Cs6VW6Z/view?usp=sharing

因此,当在A.Reader(连续版本)中打开PDF时,它说证书无效,因为对此文档进行了更改,使签名无效。

但我看不出出有什么问题。我们自己的应用程序只添加了一个签名(证书),该应用程序为数千个其他 PDF 添加了正确的签名。 未执行其他更改。使用我们自己的代码验证哈希值或使用带有以下代码的 PDFBox2 表示签名有效 (true)。

使用此代码验证:

    byte[] pdfByte;
    PDDocument pdfDoc = null;
    SignerInformationVerifier verifier = null;
    try
    {
        pdfByte = FileUtils.readFileToByteArray(new File(FOLDEROUT, "Example-link-fails.pdf"));  
        pdfDoc = PDDocument.load(new File(FOLDEROUT, "Example-link-fails.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();
        }
    }

那么,为什么A.Reader会抱怨呢?

备注:其他带有链接的PDF文件被A.Reader接受,所以现在一无所知。

非常感谢任何帮助((慢慢)疯狂):-(

PDF 签名 验证

评论


答:

0赞 mkl 4/13/2023 #1

页面注释数组中存在错误:

1 0 obj 
<<
  /Annots [24 0 R 39 0 R ] 
  /CropBox [0 0 612 792 ] 
  /Type /Page
  ...
>>
endobj
39 0 obj 
[38 0 R ] 
endobj

这显然是不正确的,Annots 数组应包含对与页面关联的注释的间接引用,而不是对嵌套数组的引用。

此类错误可能会使 Adobe Acrobat 在加载时尝试修复 PDF(在内存中),而此类修复可能会导致签名验证失败。

评论

0赞 user1391606 4/15/2023
嗨,@MKL,你是最棒的!谢谢解决这个问题。是否存在可以检测此类问题(或检查是否存在任何语法错误)的工具?
0赞 mkl 4/15/2023
在这种情况下,Acrobat 的印前检查工具(语法检查配置文件)显示批注中存在问题。但是,通常没有常用工具显示问题。