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