Instalación

Lo primero que vamos a hacer es instalar la biblioteca que da soporte para acceder a los certificados del DNIe a través del estándar PKCS#11, que la encontramos en la página de descargas del DNIe. Encontrarás paquetes .deb y .rpm, así como el código fuente. Instala como prefieras.

Sería genial poder usar OpenSC, que viene empaquetado en casi todas las distros, pero el soporte para DNIe 3.0 vendrá en OpenSC 0.17. Creo que con versiones anteriores de DNIe sí que funciona; si alguien lo puede comprobar, que me lo diga y actualizo las instrucciones.

Ahora necesitamos descargar JSignPdf y descomprimir el zip en una carpeta cualquiera.

Por último, instala Java:

$ pkcon install java-1.8.0-openjdk

Configuración

Dentro de la carpeta donde descargamos JSignPdf hay una carpeta llamada conf, que tiene dos ficheros. Hay que editar ambos.

En el fichero conf.properties hay que descomentar la línea que pone pkcs11config.path=conf/pkcs11.cfg, simplemente eliminando el # que hay delante.

En el fichero pkcs11.cfg hay que cambiar la línea que empieza por library= y dejarla así: library=/usr/lib64/libpkcs11-dnie.so. Asegúrate también de que no esté comentada.

No estoy seguro de si necesitarás instalar las mismas dependencias que para usar el DNIe en Firefox.

Ejecución

GUI

Una vez lo has configurado, introduce tu DNIe en tu lector y ejecuta:

$ cd carpeta/de/descarga
$ java -jar JSignPdf.jar

Si todo ha ido bien, te saldrá una ventana como esta:

Captura de pantalla de 2016-07-07 18-41-48.png

  1. Deberás elegir PKCS11 como Keystore type. Si no te sale esa opción es que te has saltado algún paso de instalación o configuración.
  2. Rellena también el Keystore password con el PIN de tu DNIe.
  3. Marca la casilla Advanced view, pulsa el botón Load keys y selecciona CertFirmaDigital en el campo KeyAlias.
    1. Esto es porque el DNIe incluye una clave para autentificarse y otra para firmar. Si no la eliges, puede que firmaras el PDF con la de autentificación, y esto no tendría validez legal.
  4. Usa el botón Browse... de Input PDF file para escoger el PDF que vas a firmar.
  5. Por defecto, te guardará el PDF firmado al lado del original, con el sufijo _signed. Puedes cambiar esto en el campo Output PDF file (optional).
  6. Si tu documento ya tiene alguna firma electrónica, marca la casilla Append signature to the existing ones, para que tu firma no reemplace las del PDF, sino que se añada a ellas. Esto puede pasar si, por ejemplo, estás firmando una nómina o contrato que ya viene firmada por el otro interesado.
  7. Si no quieres que tu firma sea válida si el PDF sufre modificaciones, selecciona Certification level > No changes allowed.
  8. Selecciona Hash algorithm > SHA256. Es lo más alto que me ha funcionado a mí. Cuanto más alto, mayor seguridad.
  9. Si quieres que la firma quede visible en el documento, marca Visible signature.
    • Si quieres escoger dónde debe quedar tu firma visible, ve a Settings > Position > Preview & Select, marca un recuadro donde quieres que aparezca, y pulsa Close > Close.
  10. Pulsa Sign It para firmar el documento.
  11. Cierra todas las ventanas.

Error al intentar firmar varias veces seguidas

Si lo intentas, te puede aparecer este error en la ventana de mensajes:

ERROR Problem occured
java.security.ProviderException: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_USER_NOT_LOGGED_IN
    at sun.security.pkcs11.P11Signature.engineSign(P11Signature.java:591)
    at java.security.Signature$Delegate.engineSign(Signature.java:1207)
    at java.security.Signature.sign(Signature.java:579)
    at com.lowagie.text.pdf.PdfPKCS7.getEncodedPKCS7(Unknown Source)
    at net.sf.jsignpdf.SignerLogic.signFile(SignerLogic.java:387)
    at net.sf.jsignpdf.SignerLogic.run(SignerLogic.java:114)
    at java.lang.Thread.run(Thread.java:745)
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_USER_NOT_LOGGED_IN
    at sun.security.pkcs11.wrapper.PKCS11.C_Sign(Native Method)
    at sun.security.pkcs11.P11Signature.engineSign(P11Signature.java:582)
    ... 6 more
INFO  Finished: Creating of signature failed.

Esto se debe a que el DNIe 3.0 exige que se meta la contraseña cada vez que se usa. No es como otras tarjetas inteligentes, que te permiten iniciar sesión y usarla cuantas veces quieras hasta que la cierras. Tendrás que cerrar y volver a abrir el programa cada vez que quieras firmar algo. Tranquilo, la mayoría de opciones se quedan memorizadas.

CLI

Este programa también funciona por línea de comandos, pero no me apetece ahora explicarlo todo, así que te dejaré el comando que necesitas para saber cómo hacer lo que necesites:

$ cd carpeta/de/descarga
$ java -jar JSignPdf.jar --help

Verificar la firma

En estos momentos el lector de PDF de GNOME todavía no soporta la verificación de firmas, y no conozco ningún otro programa GUI en Linux que lo soporte.

El propio JSignPdf incluye una utilidad llamada Verifier.jar para trabajar por CLI, pero si tienes Adobe Acrobat PDF Reader podrás verificarla. Siempre puedes intentar instalarlo con Wine.