使用iText从PCKS7签名的PDF文件中获取哈希/摘要

我正在编写一个Java Web服务,用来自网络中某些客户的iText签署PDF文档。 文档正确签名,可以使用外部工具进行validation。 但是,由于某些法律限制,为了将此文档存储在官方文档库中,我必须提供签名中的哈希/摘要消息。

我已经尝试了几乎任何东西来获取该哈希值,但我能得到的最接近的是使用此代码片段获取整个签名(CERT + HASH / DIGEST + TIMESTAMP)作为字符串(原谅字符串和[1]因为我我只是测试如何做到这一点:

PdfReader reader = new PdfReader(path); File temp = TempFileManager.createTempFile("aasd2sd", "asdasda222cff"); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(temp)); stamper.setRotateContents(false); PdfString firma = (PdfString) stamper.getAcroFields().getSignatureDictionary("Signature1").get((PdfName)stamper.getAcroFields().getSignatureDictionary("Signature1").getKeys().toArray()[1]); 

据我所知,我得到了一个DER-enconded PKCS7签名。 但是,我不知道如何解读/读取这些信息以便达到目的。

任何想法?

谢谢,克里斯。

首先,签名中不一定哈希/摘要消息,如果PKCS#7 / CMS签名通常涉及多个哈希值,参见 这个答案是数字签名中pdf的消息摘要

考虑到你需要摘要来满足一些法律限制 ,我认为你是在签名属性MessageDigest的值之后(如果存在) ETSI.CAdES.detachedadbe.pkcs7.detached类型的PDF签名是已签名字节范围的摘要。


如果你想使用iText类(即不是安全提供程序类),你必须克服你所追求的值存储在私有成员( PdfPKCS7.digestAttr )中的小问题。 但是,有些reflection允许您访问它:

 void extractHashes(PdfReader reader) throws Exception { AcroFields acroFields = reader.getAcroFields(); List names = acroFields.getSignatureNames(); for (String name: names) { PdfPKCS7 pdfPkcs7 = acroFields.verifySignature(name); pdfPkcs7.verify(); Field digestAttrField = PdfPKCS7.class.getDeclaredField("digestAttr"); digestAttrField.setAccessible(true); byte[] digestAttr = (byte[]) digestAttrField.get(pdfPkcs7); // process the digest value in digestAttr } } 

您可以在更完整的示例ExtractHash.java中找到使用的方法,该示例在PDF文档中输出gigest算法和签名字段的摘要值,例如:

 FirstPage11P0022AD_20150202164018_307494.pdf Signature1 Digest algorithm: SHA1 Hash: 4ac0ed7c2ec611d491f37b5ca74598237b85dbab