/** * <a href="http://stackoverflow.com/questions/43511558/how-to-set-attributes-for-existing-pdf-that-contains-only-images-using-java-itex"> * how to set attributes for existing pdf that contains only images using java itext? * </a> * <p> * The OP indicated in a comment that he searches a solution without a second file. * This test shows how to work with a single file, by first loading the file into a byte array. * </p> */ @Test public void testChangeTitleWithoutTempFile() throws IOException, DocumentException { File singleFile = new File(RESULT_FOLDER, "eg_01-singleFile.pdf"); try ( InputStream resource = getClass().getResourceAsStream("eg_01.pdf") ) { Files.copy(resource, singleFile.toPath()); } byte[] original = Files.readAllBytes(singleFile.toPath()); PdfReader reader = new PdfReader(original); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(singleFile)); Map<String, String> info = reader.getInfo(); info.put("Title", "New title"); info.put("CreationDate", new PdfDate().toString()); stamper.setMoreInfo(info); ByteArrayOutputStream baos = new ByteArrayOutputStream(); XmpWriter xmp = new XmpWriter(baos, info); xmp.close(); stamper.setXmpMetadata(baos.toByteArray()); stamper.close(); reader.close(); }
@SuppressWarnings("deprecation") public void preClose() throws Exception { if (dateTime != null) sap.setSignDate(StringUtils.dateToCalendar(dateTime)); sap.setAcro6Layers(false); sap.setCertificate(x509Certificate); //sap.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKMS, PdfName.ETSI_CADES_DETACHED); // PdfName.ADBE_PKCS7_DETACHED if (dateTime != null) dic.setDate(new PdfDate(sap.getSignDate())); dic.setName(X509Utils.getCN(x509Certificate)); dic.setCert(x509Certificate.getEncoded()); sap.setCryptoDictionary(dic); /* * PdfDictionary dic = new PdfDictionary(); * dic.put(PdfName.FT, PdfName.SIG); * dic.put(PdfName.FILTER, PdfName.ADOBE_PPKMS); * dic.put(PdfName.SUBFILTER, PdfName.ETSI_CADES_DETACHED); * dic.put(PdfName.M, new PdfDate(sap.getSignDate())); * dic.put(PdfName.NAME, new PdfString(Utils.getCN(cert))); * sap.setCryptoDictionary(dic); */ HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>(); exc.put(PdfName.CONTENTS, new Integer(csize * 2 + 2)); sap.preClose(exc); dataToSign = IOUtils.toByteArray(sap.getRangeStream()); }
/** * This method extracts integrated signature information from the PDF * this class is instantiated with. * @return */ //@SuppressWarnings("unchecked") public Map<String, SignatureData> extractSignatures() { final Map<String, SignatureData> result = new HashMap<String, SignatureData>(); final AcroFields fields = reader.getAcroFields(); for (String name: fields.getSignatureNames()) { PdfDictionary sigDict = fields.getSignatureDictionary(name); PdfString contents = sigDict.getAsString(PdfName.CONTENTS); PdfName subFilter = sigDict.getAsName(PdfName.SUBFILTER); if (contents != null) { byte[] contentBytes = contents.getOriginalBytes(); byte[] containerBytes = null; /* ContentInfo contentInfo = null; try { contentInfo = new ContentInfoImpl(contentBytes); byte[] bytes = contentInfo.getEncoded(); if (bytes.length <= contentBytes.length) { boolean equal = true; for (int i = 0; i < bytes.length; i++) { if (bytes[i] != contentBytes[i]) { System.err.println("Re-encoded differs at " + i); equal = false; break; } } if (equal) containerBytes = bytes; } else { System.err.println("Re-encoded data too long"); } } catch (GeneralSecurityException e) { System.err.println("Failure decoding content as container."); e.printStackTrace(); } */ Date signingTime = null; Object pdfDateEntry = sigDict.get(PdfName.M); if (pdfDateEntry != null) { Calendar cal = PdfDate.decode(pdfDateEntry.toString()); if (cal != null) { signingTime = cal.getTime(); } } result.put(name, new SignatureData(/*contentInfo,*/ containerBytes, contentBytes, subFilter, signingTime)); } } return result; }
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; }