iText es una librería Java gratuita para la generación de documentos PDF de forma dinámica. Es una de las más utilizadas por su simplicidad, disponibilidad de ejemplos y documentación (incluso se ha publicado un libro) y funcionalidades.
A parte del soporte para la generación de documentos PDF, ofrece una serie de características adicionales que pueden resultar muy interesantes:
- Inclusión de códigos de barras tanto lineales como 2D (PDF 417).
- Posibilidad de firma digital de documentos PDF de forma que Adobe Acrobat sea capaz de procesar y validar esta información.
Respecto a la firma digital, es posible firmar un documento PDF existente con un certificado X509 en formato PKCS#12 (en explorer se exportan como .PFX) de forma directa:
KeyStore ks = KeyStore.getInstance("pkcs12");
ks.load(new FileInputStream("certificado.pfx"), "mi_password".toCharArray());
String alias = (String) ks.aliases().nextElement();
PrivateKey key = (PrivateKey) ks.getKey(alias, "mi_password".toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
PdfReader reader = new PdfReader("documento.pdf");
FileOutputStream fout = new FileOutputStream("documento_firmado.pdf");
PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0', new File("/tmp"));
PdfSignatureAppearance sap = stp.getSignatureAppearance();
sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
sap.setReason("Prueba de firma digital con iText");
sap.setLocation("Spain");
sap.setContact("Ricardo Borillo");
stp.close();
Hay disponible una descripción más amplia de todo el proceso en esta dirección.
Así es como se vería el documento firmado cundo lo visualizamos con el Acrobat Reader:

Y la información de la firma en la pestaña vertical de la parte izquierda (Firmas):

[...] En un reciente artículo sobre firma digital de documentos PDF con iText veiamos como realizar la firma aislada de documentos PDF. Para los que utilicen Cocoon, existe una forma de poder firmar los documentos PDF que se generen dinámicamente como resultado de una transformación. El proceso pasa por implementar nuestro propio serializer. [...]