Firmar documento PDF
Vamos a ver como firmar un documento pdf, con un certificado.
Para obtener el certificado tenemos 2 opciones:
1: Generar a partir de herramientas como keytool, openssl, etc, en este caso el certificado solo serviría con fines de pruebas.
2: Comprar un certificado a un proveedor que garantice la valides.
Para generar con keytool aquí el código:
keytool -genkey -alias mycert -keyalg RSA -keypass cert123 -storepass changeit -keystore D:\store\mystore.jks
Se ha creado un Store con un certificado.
Alias del certificado: mycert
Clave del certificado: cert123
Clave de Store: changeit
Si compramos a un proveedor el archivo sera :
Nombre del certificado: xxxxx.pfx
Clave del certificado: proporcionado por el proveedor
Documento antes de firmar.
Documento después de firmar.
Ahora vamos a ver el código para firmar el archivo con el certificado generado con el keytool.
private static void signedfromKeyTool() throws Exception {
String input_pdf = "D:\\store\\input.pdf";
String ouput_pdf = "D:\\store\\ouput.pdf";
String store_pass = "changeit";
String cert_pass = "cert123";
/**
* Instanciamos el keystore
*/
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("D:\\store\\mystore.jks"), store_pass.toCharArray());
/**
* Recuperamos el alias, como solo hay un certificado ks.aliases()
* recupera el alias.
*/
Enumeration<String> aliases = ks.aliases();
String alias = aliases.nextElement();
/**
* Obtenemos la entidad del certificado.
*/
KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias, new KeyStore.PasswordProtection(cert_pass.toCharArray()));
/**
* Bloque de la libreria itext para agregar un certificado a un pdf
*/
PdfReader reader = new PdfReader(input_pdf);
FileOutputStream fout = new FileOutputStream(ouput_pdf);
PdfStamper stp = null;
stp = PdfStamper.createSignature(reader, fout, '\0');
PdfSignatureAppearance sap = stp.getSignatureAppearance();
sap.setCrypto(keyEntry.getPrivateKey(), keyEntry.getCertificateChain(), null, PdfSignatureAppearance.WINCER_SIGNED);
/**
* Agregamos un imagen al documento pdf para indicar la firma
*/
Image image = Image.getInstance("D:\\store\\image3.png");
sap.setImage(image);
Rectangle cropBox = reader.getCropBox(1);
float width = 120;
float height = 120;
sap.setVisibleSignature(new Rectangle(cropBox.getLeft(), cropBox.getTop(), cropBox.getLeft(width), cropBox.getTop(height)), 1, "sig");
stp.close();
}
Y por ultimo vamos a ver el código para firmar con el certificado en formato PFX
private static void signedFromPFX() throws Exception {
String input_pdf = "D:\\store\\input.pdf";
String ouput_pdf = "D:\\store\\ouput.pdf";
String cert_pass = "xxxxx";
/**
* Instanciamos el keystore
*/
KeyStore ks = KeyStore.getInstance("pkcs12", "SunJSSE");
ks.load(new FileInputStream("D:\\store\\xxxxx.pfx"), cert_pass.toCharArray());
/**
* Recuperamos el alias, como solo hay un certificado ks.aliases()
* recupera el alias.
*/
Enumeration<String> aliases = ks.aliases();
String alias = aliases.nextElement();
/**
* Obtenemos la entidad del certificado.
*/
KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias, new KeyStore.PasswordProtection(cert_pass.toCharArray()));
/**
* Bloque de la libreria itext para agregar un certificado a un pdf
*/
PdfReader reader = new PdfReader(input_pdf);
FileOutputStream fout = new FileOutputStream(ouput_pdf);
PdfStamper stp = null;
stp = PdfStamper.createSignature(reader, fout, '\0');
PdfSignatureAppearance sap = stp.getSignatureAppearance();
sap.setCrypto(keyEntry.getPrivateKey(), keyEntry.getCertificateChain(), null, PdfSignatureAppearance.WINCER_SIGNED);
/**
* Agregamos un imagen al documento pdf para indicar la firma
*/
Image image = Image.getInstance("D:\\store\\image3.png");
sap.setImage(image);
Rectangle cropBox = reader.getCropBox(1);
float width = 120;
float height = 120;
sap.setVisibleSignature(new Rectangle(cropBox.getLeft(), cropBox.getBottom(), cropBox.getLeft(width), cropBox.getBottom(height)), 1, "sig");
stp.close();
}
La librería para firmar un documento pdf es itext, a continuación la dependencia maven.
<!-- https://mvnrepository.com/artifact/com.lowagie/itext -->
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>
Espero puedan integrar en sus aplicaciones.