Description

Recently I had to research a solution to sign a PDF document. I think I am not the one to have this sort of problem, so I put here the result of my tests for the community.

With this you can create and sign a PDF document with a PKCS12 certificat. When you signed a document you include in this document your numeric signature.
It add automaticly this sort of pictures in PDF document and moreover to signed it. So it forbid any modifications by saying the transmitter (the signatory of the document).

Tools used

  • Acrobat reader 7.x ou sup Fo read a PDf document
  • iText 2.xJava librarie tools to build and sign PDF
  • bouncycastle.org for itext (bcprov)
  • A PKCS12 certificat (.p12) (buy or self signed) : Warning if you make a self signed certicficat you can not verify chain certificat

Sample (source code)

Comme vous pouvez le voir le code java pour réaliser cela est très simple il est divisé en deux parties :

  • buildPDF methode : to create a PDF document (unsigned) (it’s an option)
  • signPdf methode : to sign the PDF document
package com.berthou.test.pdf ;
 
import java.io.*;
import java.security.*;
import java.security.cert.Certificate;
 
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;
 
public class sign_pdf  {
 
	/**
	 * Nom du document PDF généré non signé
	 */
	static String fname  = "D:\\HelloWorld.pdf" ;
 
	/**
	 * Nom du document PDF généré signé
	 */
	static String fnameS = "D:\\HelloWorld_sign.pdf" ;
 
	public static void main(String[] args) {
		try {
			sign_pdf.buildPDF() ;
			sign_pdf.signPdf() ;
		}
		catch(Exception e) { }
	}
 
	/**
	 * Création d'un simple document PDF "Hello World"
	 */
	public static void buildPDF() {
 
		// Creation du document
		Document document = new Document();
 
		try {
			// Creation du "writer" vers le doc
			// directement vers un fichier
			PdfWriter.getInstance(document,
					new FileOutputStream(fname));
			// Ouverture du document
			document.open();
 
			// Ecriture des datas
			document.add(new Paragraph("Hello World"));
 
		} catch (DocumentException de) {
			System.err.println(de.getMessage());
		} catch (IOException ioe) {
			System.err.println(ioe.getMessage());
		}
 
		// Fermeture du document
		document.close();
 
	}
	/**
	 * Signature du document
	 */
	public static final boolean signPdf()
			throws IOException, DocumentException, Exception
	{
		// Vous devez preciser ici le chemin d'acces a votre clef pkcs12
		String fileKey          = "C:\\MonRep\\MaClef.p12" ;
		// et ici sa "passPhrase"
		String fileKeyPassword  = "MonPassword" ;
 
		try {
			// Creation d'un KeyStore
			KeyStore ks = KeyStore.getInstance("pkcs12");
			// Chargement du certificat p12 dans el magasin
			ks.load(new FileInputStream(fileKey), fileKeyPassword.toCharArray());
			String alias = (String)ks.aliases().nextElement();
			// Recupération de la clef privée
			PrivateKey key = (PrivateKey)ks.getKey(alias, fileKeyPassword.toCharArray());
			// et de la chaine de certificats
			Certificate[] chain = ks.getCertificateChain(alias);
 
			// Lecture du document source
			PdfReader pdfReader = new PdfReader((new File(fname)).getAbsolutePath());
			File outputFile = new File(fnameS);
			// Creation du tampon de signature
			PdfStamper pdfStamper;
			pdfStamper = PdfStamper.createSignature(pdfReader, null, '\0', outputFile);
			PdfSignatureAppearance sap = pdfStamper.getSignatureAppearance();
			sap.setCrypto(key, chain, null, PdfSignatureAppearance.SELF_SIGNED);
			sap.setReason("Test SignPDF berthou.mc");
			sap.setLocation("");
			// Position du tampon sur la page (ici en bas a gauche page 1)
			sap.setVisibleSignature(new Rectangle(10, 10, 50, 30), 1, "sign_rbl");
 
			pdfStamper.setFormFlattening(true);
			pdfStamper.close();
 
			return true;
		}
		catch (Exception key) {
			throw new Exception(key);
		}
	}
}

Sample PDF generate

HelloWorld_sign.pdf

Be Sociable, Share!