Obtaining the hash/digest from a PCKS7 signed PDF file with iText

跟風遠走 提交于 2019-12-30 07:43:32

问题


I'm writing a Java web service that signs PDF documents with iText from some clients in the network. Documents are being signed correctly, and can be verified with external tools. However, due to some legal restrictions in order to store this document in an official documentary repository I have to provide the hash/digest message from the signature.

I have tried almost anything to get to that hash, but the closest that I can get is to obtain the whole signature (CERT+HASH/DIGEST+TIMESTAMP) as a string with this code snippet (forgive the strings and [1] since I'm just testing how to do it):

    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]);

With that I get a DER-enconded PKCS7 Signature, as far as I know. But, I don't know how to decode/read this info in order to get to the hast.

Any idea?

Thanks, Cris.


回答1:


First of all, there is not necessarily the hash/digest message from the signature, in case of PKCS#7 / CMS signatures usually multiple hashes are involved, cf. this answer to Message digest of pdf in digital signature.

Considering that you need the digest to fulfill some legal restrictions, though, I assume you are after the value of the signed attribute MessageDigest which (if it is present) for ETSI.CAdES.detached or adbe.pkcs7.detached type PDF signatures is the digest of the signed byte ranges.


If you want to do that using iText classes (i.e. not security provider classes), you have to overcome the small issue that the value you are after is stored in a private member (PdfPKCS7.digestAttr). Some reflection allows you to access it, though:

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 
    }
}

You can find the method used in a more complete example ExtractHash.java which outputs gigest algorithm and digest value of signature fields in a PDF document, e.g.:

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


来源:https://stackoverflow.com/questions/29939831/obtaining-the-hash-digest-from-a-pcks7-signed-pdf-file-with-itext

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!