验证 iText PDF 中已签名和受保护的 PDF 证书 Java

Verifying certificate of signed and secured PDF in iText PDF Java

我使用 Adob​​e Acrobat 保护了一个 PDF,然后对其进行了签名,但是当我尝试使用 iText 验证签名时,出现错误

Exception in thread "main" java.lang.IllegalArgumentException: can't decode PKCS7SignedData object
at com.itextpdf.text.pdf.security.PdfPKCS7.<init>(PdfPKCS7.java:214)
at com.itextpdf.text.pdf.AcroFields.verifySignature(AcroFields.java:2427)
at com.itextpdf.text.pdf.AcroFields.verifySignature(AcroFields.java:2373)
at C5_01_SignatureIntegrity.verifySignature(C5_01_SignatureIntegrity.java:19)
at C5_03_CertificateValidation.verifySignature(C5_03_CertificateValidation.java:42)
at C5_01_SignatureIntegrity.verifySignatures(C5_01_SignatureIntegrity.java:32)
at C5_03_CertificateValidation.main(C5_03_CertificateValidation.java:134)

我正在使用 https://developers.itextpdf.com/examples/security/digital-signatures-white-paper/digital-signatures-chapter-5#887-c5_03_certificatevalidation.java

中的示例代码

我使用了通用 PDF,密码受 Adob​​e Acrobat 保护,然后从 Adob​​e Acrobat 自签名。

iText 5 安全性 API 确实无法验证加密文档的签名。

原因是解密代码不足:就像大多数其他字符串一样,它也“解密”签名词典的 Contents 密钥的值。但是,由于这些一开始并没有加密,因此这种“解密”实际上会扰乱它们。因此,PdfPKCS7 class 无法将它们解析为签名容器并抛出观察到的异常。

与此相反,iText 7 安全性 API 可以验证此类签名。

与上述 iText 5 情况不同的是,这里对 PDF 字符串的解密被推迟到实际使用它们的内容时。签名 API,在访问内容之前,将 Contents PDF 字符串标记为 未加密。因此,可以按原样访问它们的原始值。

(这有点冒险,因为某些代码可能会预先检索这些字符串的内容,从而导致“解密”。另一方面,这消除了解析 PdfReader 中的 PDF AcroForm 信息的必要性; 由于一般的表单解析和特殊的签名解析不是内核模块的一部分,因此这种必要性要么会导致代码重复,要么会导致多个模块合并。)

此问题在 中有更详细的介绍。