Tips, Soluciones y Novedades en Tecnología

19/09/2018

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.


10/09/2018

Insertar Imagen en pdf






En muchos casos requerimos insertar una imagen a un archivo PDF, para formatos,plantillas etc.



En esta entrada vamos a explicar paso a paso como insertar en cada hoja del documento PDF.





Como primer paso agregamos la dependencia Maven








<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<!-- ITEXTPDF -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.4.2</version>
</dependency>
<!-- /ITEXTPDF-->




Ahora implementamos el método encargado de la inserción de la imagen en el archivo PDF.



Este método inserta la imagen en cada hoja del PDF, si la hoja se encuentra vertical ú horizontal, no tiene problemas en insertar.



El método para realizar la conversión es el siguiente.






public static void process(File input, File ouput, File logo, int x, int y) throws Exception {
PdfReader reader = new PdfReader(input.getAbsolutePath());
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(ouput.getAbsolutePath() + File.separator + input.getName()));
for (int i = 1; i <= reader.getNumberOfPages(); i++) {;
Image image = Image.getInstance(logo.getAbsolutePath());
image.setAbsolutePosition(y, reader.getPageSize(i).getHeight() - image.getScaledHeight() - x);
PdfContentByte under = stamper.getUnderContent(i);
under.addImage(image);
}
stamper.close();
reader.close();
}






Los parámetros de entrada son:



input: el archivo pdf a insertar la imagen

ouput: el archivo pdf para la salida

logo: el archivo imagen a insertar

x: Distancia  izquierda horizontal , default 25

y: Distancia izquierda vertical, default 25







Para determinar el X y Y, se debe probar hasta determinar la posición correcta a insertar.



A continuación la ejecución del método pasando los parámetros anteriormente mencionados.






    public static void main(String[] args) throws Exception {
File pdf_input = new File("/opt/input/plantilla.pdf");
File pdf_ouput = new File("/opt/input/logo.png");
File file_imagen = new File("/opt/input/plantilla_new.pdf");
int x = 25;
int y = 25;
process(pdf_input, pdf_ouput, file_imagen, x, y);
}






Saludos.