I need to implement signing a pdf document in two steps. In the first step I need to calculate a pdf digest and in the second step, I need to sign this document.
I have a problem with step 1 (calculating pdf digest). If I run the digest calculation several times with identical data, I have different digests.
When I checked the document that has been passed to the digest calculation method, I found the Modification date was different in these calls.But If I do it with the PdfBox library, I always get correct results, and the Modification Date doesn’t change
How can I calculate the pdf digest and don’t update the modified date?
My code looks like the following:
public class MyDigestCalculator extends ExternalBlankSignatureContainer { public byte[] pdfDigest; public MyDigestCalculator(PdfName filter, PdfName subFilter) { super(filter, subFilter); } @Override public byte[] sign(InputStream is) throws GeneralSecurityException { try { final byte[] bytes = is.readAllBytes(); final String pdf = new String(bytes); BouncyCastleDigest digestService = new BouncyCastleDigest(); pdfDigest = DigestAlgorithms.digest(new ByteArrayInputStream(bytes), “SHA-256”); return new byte[0]; } catch (IOException e) { throw new GeneralSecurityException("Can't get digest from file hash", e); } }
}
public class DocumentSigner { public String calculatePdfDigest(byte[] pdfBytes, SignatureProperties signature, boolean lockFields, Calendar signDate) throws IOException, GeneralSecurityException { final PdfDocument pdfDocument = createPdfDocument(pdfBytes); PdfAcroForm acroForm = PdfAcroForm.getAcroForm(pdfDocument, false); acroForm.setSignatureFlags(PdfAcroForm.SIGNATURE_EXIST); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfReader reader = new PdfReader(new ByteArrayInputStream(pdfBytes)); PdfSigner signer = new PdfSigner(reader, baos, new StampingProperties().useAppendMode()); signer.setSignDate(signDate); MyDigestCalculator calcDigest = new MyDigestCalculator(PdfName.Adobe_PPKLite, PdfName.Adbe_pkcs7_detached); signer.signExternalContainer(calcDigest, 8120); pdfBytes = baos.toByteArray(); String digest = (digestHash != null ? new BigInteger(1, calcDigest.pdfDigest).toString(16) : null); return digest;
}
} 7 Related questions 4398 How do I avoid checking for nulls in Java? 4701 How do I read / convert an InputStream into a String in Java? 4089 How do I generate random integers within a specific range in Java? Related questions 4398 How do I avoid checking for nulls in Java? 4701 How do I read / convert an InputStream into a String in Java? 4089 How do I generate random integers within a specific range in Java? 3723 How can I create a memory leak in Java? 3966 How do I efficiently iterate over each entry in a Java Map? 3494 How do I convert a String to an int in Java? 2663 How do I call one constructor from another in Java? 3208 How do I test a class that has private methods, fields or inner classes? 2701 How do I determine whether an array contains a particular value in Java? 2718 How can I fix 'android.os.NetworkOnMainThreadException'? Load 7 more related questions Show fewer related questions Reset to default