Formulario para firmar PDF con Python - Seleccionar P12, contraseña y archivo

Python – Firmar PDF con P12 y Flask

En este post te compartiré los resultados de mi investigación sobre cómo firmar, digitalmente, un documento PDF usando un certificado con extensión P12 y la librería endesive.

Al final terminé creando una aplicación web con Flask que permite que elijas el certificado, el PDF y la contraseña para devolverte el PDF pero firmado digitalmente.

Ten en cuenta que yo probé con un certificado de prueba generado por mí mismo, así que no sé si esto funcione con algo real.

Firmando PDF

En el repositorio oficial de endesive ya está un ejemplo de cómo firmar un PDF. Yo modifiqué la función para que devolviera los bytes del PDF firmado en lugar de guardarlo en el almacenamiento local ya que los necesito para enviarlos con Flask.

Al final separé todo en un archivo llamado firmador.py y se ve así:

Y sí, solo comenté las partes que no me servían. No eliminé nada por si necesitaba volver a lo anterior… ya sabes, cosas de programadores.

Una cosa que quiero contarte es que si especificas signature_img y no especificas signature entonces se va a firmar usando una imagen. Esa imagen puede ser una foto de la firma manuscrita real, solo para que se vea más bonito.

Ahora simplemente invoco esa función desde Flask como verás a continuación.

Formulario para firmar PDF con Python

Formulario para firmar PDF con Python - Seleccionar P12, contraseña y archivo
Formulario para firmar PDF con Python – Seleccionar P12, contraseña y archivo

Antes de continuar veamos el formulario. El mismo necesitará 2 archivos que serán el PDF y el P12, y un tipo texto (o mejor dicho, password):

Es una plantilla que será servida con Flask en determinada ruta. El JavaScript que ves es para que se coloque el nombre del archivo seleccionado en el input, solo eso.

Firmando PDF con Python y Flask

Ahora veamos la configuración de Flask que es todo el servidor. Aquí aunque parezca simple tuve que investigar cómo leer el archivo sin almacenarlo temporalmente (ya que vamos a firmar algo, no debemos dejar la firma o cosas similares en el servidor).

La magia está en la línea 15. Ahí se va a procesar lo que el formulario envíe.

Extraemos la firma, la contraseña y el PDF. Luego invocamos a la función del firmador que nos va a devolver el PDF firmado como un montón de bytes (igual nosotros le enviamos la firma y el PDF original como muchos bytes).

Finalmente rebobinamos el archivo en la línea 24 y lo servimos directamente como un adjunto en el navegador.

Al final el usuario presionará el botón “Firmar” y unos segundos después se le estará preguntando en dónde guardar el PDF ya firmado.

Analizando documento PDF firmado

Si todo va bien entonces tendremos el PDF ya firmado con un certificado P12 o PKCS 12 usando endesive y Flask.

Al analizarlo con Adobe Acrobat Reader vemos que ya está firmado correctamente pero que la firma es inválida porque como ya dije anteriormente yo generé mi certificado para probar.

Analizando documento PDF firmado con P12
Analizando documento PDF firmado con P12

Poniendo todo junto

Te voy a dejar el código completo en mi GitHub. Dentro del mismo encontrarás un README con las instrucciones que igual colocaré aquí (aunque lo más actualizado estará en el repositorio):

Debe decir algo como:

* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on all addresses (0.0.0.0)
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://127.0.0.1:81
* Running on http://192.168.100.6:81 (Press CTRL+C to quit)

Navegar a http://localhost:81/ y usar la webapp

Si aparece algo como “python no se reconoce como un comando externo” o cosas así, revisar que se haya agregado correctamente a la PATH.

Finalmente te dejo con más tutoriales de Python en mi blog.

Encantado de ayudarte


Estoy disponible para trabajar en tu proyecto, modificar el programa del post o realizar tu tarea pendiente, no dudes en ponerte en contacto conmigo.

No te pierdas ninguno de mis posts

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

Dejar un comentario