/** * <a href="http://stackoverflow.com/questions/36589698/error-while-digitally-signing-a-pdf"> * Error while digitally signing a PDF * </a> * <p> * Tried to reproduce the OP's issue with my own test PDF and key. But it worked alright. * </p> */ @Test public void signLikeJackSparrow() throws GeneralSecurityException, IOException, DocumentException { final String SRC = "src/test/resources/mkl/testarea/itext5/extract/test.pdf"; final String DEST = new File(RESULT_FOLDER, "test-JackSparrow-%s.pdf").getPath(); C2_01_SignHelloWorld_sign(SRC, String.format(DEST, 1), chain, pk, DigestAlgorithms.SHA256, "BC", CryptoStandard.CMS, "Signed for Testing", "Universe"); C2_01_SignHelloWorld_sign(SRC, String.format(DEST, 2), chain, pk, DigestAlgorithms.SHA512, "BC", CryptoStandard.CMS, "Test 2", "Universe"); C2_01_SignHelloWorld_sign(SRC, String.format(DEST, 3), chain, pk, DigestAlgorithms.SHA256, "BC", CryptoStandard.CADES, "Test 3", "Universe"); }
public DigestInfo preSign(List<DigestInfo> arg0, List<X509Certificate> certificates) throws NoSuchAlgorithmException { System.out.println("SignatureServiceImpl::preSign"); HttpSession session = getSession(); SignatureRequest request = (SignatureRequest)session.getAttribute(BeidConstants.SIGNATUREREQUEST_SESSION_NAME); ContentStream content = request.getDocument().getContentStream(); try { Certificate[] chain = new Certificate[certificates.size()]; int index = 0; for (X509Certificate cert: certificates) { //System.out.println("CERT: "+cert); chain[index++] = cert; } // we create a reader and a stamper PdfReader reader = new PdfReader(content.getStream()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfStamper stamper = PdfStamper.createSignature(reader, baos, '\0'); // we create the signature appearance PdfSignatureAppearance sap = stamper.getSignatureAppearance(); request.fillAppearance(sap, reader); sap.setCertificate(chain[0]); // we create the signature infrastructure PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); dic.setReason(sap.getReason()); dic.setLocation(sap.getLocation()); dic.setContact(sap.getContact()); dic.setDate(new PdfDate(sap.getSignDate())); sap.setCryptoDictionary(dic); HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>(); exc.put(PdfName.CONTENTS, new Integer(8192 * 2 + 2)); sap.preClose(exc); ExternalDigest externalDigest = new ExternalDigest() { public MessageDigest getMessageDigest(String hashAlgorithm) throws GeneralSecurityException { return DigestAlgorithms.getMessageDigest(hashAlgorithm, null); } }; PdfPKCS7 sgn = new PdfPKCS7(null, chain, "SHA256", null, externalDigest, false); InputStream data = sap.getRangeStream(); byte hash[] = DigestAlgorithms.digest(data, externalDigest.getMessageDigest("SHA256")); Calendar cal = Calendar.getInstance(); byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, cal, null, null, CryptoStandard.CMS); sh = MessageDigest.getInstance("SHA256", "BC").digest(sh); // We store the objects we'll need for post signing in a session session.setAttribute(BeidConstants.SIGNATURE_SESSION_NAME, sgn); session.setAttribute(BeidConstants.HASH_SESSION_NAME, hash); session.setAttribute(BeidConstants.CAL_SESSION_NAME, cal); session.setAttribute(BeidConstants.SAP_SESSION_NAME, sap); session.setAttribute(BeidConstants.BAOS_SESSION_NAME, baos); DigestInfo info = new DigestInfo(sh, "SHA-256", "BeidSign"); return info; } catch(Exception e) { e.printStackTrace(); } return null; }