28
Nov
Sign a PDF document
Author: rberthou
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
15 Responses pour"Sign a PDF document"
Hi!
I must do something like this.
But I have one question.
Can I sing more than one time the same document? (sign by more than one person)
Thanks
hi u r code is very useful for i need code for verification on signed pdf please post it
Hi,
Thanks for posting such a useful topic. I followed the process described here and the pdf is signed. But while opening the file it’s showing
“At least one signature has problems”
Please help me to remove this error.
You might also want to look at this page: http://itextpdf.sourceforge.net/howtosign.html. It shows multiple examples of using iText (and iTextSharp) for signing PDF documents.
HI, can i sign multiple PDF at one time??
Yes of course, with a little modification of this sample code
Hello that’s so useful thank you very much, I’m new about that topic,where i can find the ‘fileKey’ which was given with .p12 extension? Can anybody explain the code what it’s doing please? thanks again.
Bruskvilla :
You can create a “self signed” certificate (for tests or internal use)
http://www.flatmtn.com/article/creating-pkcs12-certificates
or you buy a personal certificate (http://www.verisign.com)
and other site.
We had a similar project requiring us to sign PDF documents and print them. We tried Itext and were able to use the sample above . But unfortunately, it didn’t work for all PDF documents and didn’t support multiple signatures. We were sometime getting invalid signatures when opening the documents in different versions of Adobe Acrobat. So at the end we decided to purchase a commercial library (j100% java) called jPDFProcess. The same company also offers jPDFSecure, a cheaper library to secure and sign PDF documents. But because we needed to print the documents after signing, we ended up getting jPDFProcess.
hi
thanks about this a very good explanation ,but i have a problem , when i excecute my program a big exception ocure and my pdfs file is impty or clearly the acrobat reader can’t read it (error of decrypt…)
hi
thanks about this a very good explanation ,but i have a problem , when i excecute my program a big exception occur and my pdfs file is impty or clearly the acrobat reader can’t read it (error of decrypt…), my exception is
———————————————————————->
” Exception in thread “main” java.lang.NoClassDefFoundError: org/bouncycastle/tsp/TimeStampTokenInfo
at com.itextpdf.text.pdf.PdfSignatureAppearance.getAppearance(PdfSignatureAppearance.java:409)
at com.itextpdf.text.pdf.PdfSignatureAppearance.preClose(PdfSignatureAppearance.java:951)
at com.itextpdf.text.pdf.PdfSignatureAppearance.preClose(PdfSignatureAppearance.java:897)
at com.itextpdf.text.pdf.PdfStamper.close(PdfStamper.java:194)
at test4.test4.test4(test4.java:130)
at test4.test4.main(test4.java:30)
Caused by: java.lang.ClassNotFoundException: org.bouncycastle.tsp.TimeStampTokenInfo
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
… 6 more
”
please help me ,it’s so impotent
thanks ,
HI
no problem my program work successfully , cause i find (bctsp.jar) how cause me pb
so thanks again,
Its very Good code in the 2 min i have implemented but i m getting problem is . it showing signature but showing Message with “Validity Unknow” But i want to Show IBM
Thanks For this Code, But I have one issue My Pdf have more Than One pages and i want to sign on every pages then how can i modified Your code i have tried from lot of changes but not successful please reply me.
Hi rberthou,
Thank you for this post. It’s very interesting.
But in my case, im using USB token, and i sign a document in different way, by calling a ‘C_SignUpdate’ function in PKCS11JS library like this: pkcs11.C_SignUpdate.
So, how can i implement your solution without using .p12 file ?
Thank you in advance for help.
Ajouter une réponse