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

Java 使用iText从PCKS7签名的PDF文件中获取哈希/摘要,java,pdf,itext,pkcs#7,Java,Pdf,Itext,Pkcs#7,我正在编写一个Java web服务,它使用iText对来自网络中一些客户端的PDF文档进行签名。文件已正确签署,并可通过外部工具进行验证。但是,由于一些法律限制,为了将此文档存储在官方文档存储库中,我必须提供签名中的哈希/摘要消息 我已经尝试了几乎所有的方法来获取该散列,但是我能得到的最接近的方法是使用这个代码片段以字符串的形式获取整个签名(CERT+hash/DIGEST+TIMESTAMP)(请原谅字符串和[1],因为我只是在测试如何做): 据我所知,我得到了一个新的PKCS7签名。但是,我

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

我已经尝试了几乎所有的方法来获取该散列,但是我能得到的最接近的方法是使用这个代码片段以字符串的形式获取整个签名(CERT+hash/DIGEST+TIMESTAMP)(请原谅字符串和[1],因为我只是在测试如何做):

据我所知,我得到了一个新的PKCS7签名。但是,我不知道如何破译/阅读这些信息,以达到目的

有什么想法吗

谢谢,
Cris.

首先,签名中不一定有散列/摘要消息,在PKCS#7/CMS签名的情况下,通常涉及多个散列,参见

但是,考虑到您需要摘要来满足一些法律限制,我假设您需要签名属性
MessageDigest
的值,该属性(如果存在)用于ETSI.CAdES.detachedadbe.pkcs7.detached类型PDF签名是签名字节范围的摘要


如果您想使用iText类(即非安全提供程序类)实现这一点,则必须克服一个小问题,即您所追求的值存储在私有成员中(
PdfPKCS7.digestAttr
)。不过,某些反射允许您访问它:

void extractHashes(PdfReader reader) throws Exception
{
    AcroFields acroFields = reader.getAcroFields();
    List<String> 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 
    }
}

首先,签名中不一定有散列/摘要消息,在PKCS#7/CMS签名的情况下,通常涉及多个散列,参见

但是,考虑到您需要摘要来满足一些法律限制,我假设您需要签名属性
MessageDigest
的值,该属性(如果存在)用于ETSI.CAdES.detachedadbe.pkcs7.detached类型PDF签名是签名字节范围的摘要


如果您想使用iText类(即非安全提供程序类)实现这一点,则必须克服一个小问题,即您所追求的值存储在私有成员中(
PdfPKCS7.digestAttr
)。不过,某些反射允许您访问它:

void extractHashes(PdfReader reader) throws Exception
{
    AcroFields acroFields = reader.getAcroFields();
    List<String> 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 
    }
}

我的建议:谷歌“解码pkcs7 java”@Egl谢谢你的帮助,但我仍然有问题。通过谷歌搜索你的建议,我得到了一个与[link]类似的代码。然而,当试图用我的文件初始化CMSSignedData时,我得到了一个org.bouncycastle.cms.CMSException:IOException阅读内容。我的建议:对谷歌“decode pkcs7 java”@Egl谢谢你的帮助,但我仍然有问题。通过谷歌搜索你的建议,我得到了一个与[link]类似的代码。然而,当试图用我的文件初始化CMSSignedata时,我得到了一个org.bouncycastle.cms.CMSException:IOException阅读内容。你是一个节约者,谢谢。我知道我不应该提取摘要,但我必须继续这些限制,尽管我讨厌它们。我知道我不应该提取摘要——这本身并不是一件坏事。我真的很想知道为什么iText类会隐藏这些信息。买吧,如果你认为答案是正确的,你可以点击左边的勾号来接受它。完成!抱歉,太新,无法使用stackoverflow!再次感谢!你是个省钱的人,谢谢。我知道我不应该提取摘要,但我必须继续这些限制,尽管我讨厌它们。我知道我不应该提取摘要——这本身并不是一件坏事。我真的很想知道为什么iText类会隐藏这些信息。买吧,如果你认为答案是正确的,你可以点击左边的勾号来接受它。完成!抱歉,太新,无法使用stackoverflow!再次感谢!
FirstPage11P0022AD_20150202164018_307494.pdf
  Signature1
    Digest algorithm: SHA1
    Hash: 4ac0ed7c2ec611d491f37b5ca74598237b85dbab