Cómo instalar Firma Digital Certificada de Costa Rica en GNU/Linux

La instalación de los controladores de Firma Digital Certificada en GNU/Linux es más sencilla en la actualidad. En esta guía se propone una solución básica y luego una recomendada para hacerla compatible con algunas aplicaciones.

En cualquiera de los casos, hay que instalar el paquete pcscd y descargar el paquete correspondiente .deb o .rpm desde el sitio web de Soporte Firma Digital. Para el caso de distribuciones Debian o Linux Mint más recientes se sugiere descargar la versión .deb para Ubuntu más reciente, mientras que para distribuciones .rpm es un paquete único para todas las distribuciones basadas en .rpm.

  • Instalar el paquete pcscd. Puede instalarlo con el comando dnf o con el comando zypper (si se trata de openSUSE y derivados) en el caso de rpm, o con apt en el caso de .deb, o bien desde su gestor de paquetes alternativo o gráfico de su preferencia. Ejemplo (reemplace NOMBRECOMANDO con apt, dnf, zypper… según corresponda):
    sudo NOMBRECOMANDO install pcscd

    En algunas distribuciones puede ser necesario habilitar el servicio pcscd activado por socket, en otras viene activado de manera predeterminada:

    sudo systemctl enable --now pcscd.socket
  • Ir al sitio web https://soportefirmadigital.com/sfdj/dl.aspx?lang=es
  • En el paso “(1) Elija el instalador deseado”, elegir en el desplegable “Usuarios Linux (RPM 64 bits)”. Siga el resto de instrucciones de la página para aceptar e iniciar la descarga.
  • Tras descargarse el fichero archivador .zip, descomprimir con la herramienta de su preferencia (o con el comando unzip NOMBREDELFICHERO.zip en una ventana de terminal, desde la carpeta de descargas).
  • Instalar el paquete ubicado en la ruta Firma Digital/Idopte/ que estaba dentro del .zip, el nombre del paquete suele tener en el nombre Smart Card Middleware.
  • Instalar el paquete Agente GAUDI si se va a utilizar (probablemente). Está ubicado en Firma Digital/Agente GAUDI/

Eso sería la instalación básica, que se resume en instalar los paquetes pcscd, Idopte Smart Card Middleware y Agente GAUDI. Ver la sección Notas técnicas para más detalles.

Se agregarán otros detalles para instalación de Firmador libre y otras guías para compatibilidad con otros firmadores y autenticadores, como el de la CCSS y los de RACSA/SOIN (Tramite YA, Regístrelo, Receta digital). Mientras tanto se sugiere revisar los artículos de este blog al respecto.

Notas técnicas

Se recomienda reiniciar tras la instalación, en algunas distribuciones podría ser necesario si no funcionara.

En el momento de escribir la guía, en Debian 13 y LMDE 7 el .deb de Agente GAUDI puede fallar al instalar por una dependencia insatisfecha con libpcre3. Se puede forzar la instalación con el comando sudo dpkg --ignore-depends=libpcre3 -i agente-gaudi_*.deb, pero causará problemas de paquete roto al hacer apt upgrade, por lo que se sugiere modificar el fichero /var/lib/dpkg/status y buscar agente-gaudi. En el apartado correspondiente hay que eliminar el “libpcre3, ” de la línea de dependencias. No modificar nada nada más del fichero o se puede corromper la base de datos de paquetes instalados. Es recomendable respaldar ese fichero status antes de guardar la versión modificada.

Si no está instalado el paquete pcscd antes de instalar el paquete Idopte Smart Card Middleware, el instalador puede devolver un error de postinstalación, en particular con el paquete .deb, aunque quedará instalado de todos modos.

Para instalarlo en otras distribuciones que no utilizan paquetes .deb o .rpm, como por ejemplo Arch Linux, se recomienda analizar el contenido del fichero .rpm Se sugiere descargar cualquiera de los dos paquetes .rpm o .deb, aunque se sugiere .rpm por que tiene mayor simplicidad. En Arch Linux se puede utilizar rpmextract para extraer el contenido y luego armar manualmente su propio PKGBUILD. En otras distribuciones pueden realizar la instalación manual también de cada componente. Por ejemplo se podría observar el proceso de preinstalación y postinstalación del rpm ejecutando rpm -q --scripts SmartCardMiddleware en un sistema que lo tenga instalado, para conocer los detalles.

Si se va a crear o configurar una herramienta para acceder a las características de la tarjeta, como autenticadores o firmadores que requieran configuración manual, el instalador proporciona un librería con interfaz Cryptoki (interfaz de programación C normalizada), cuya ruta de instalación es /usr/lib/SCMiddleware/libidop11.so la cual ya viene preconfigurada en herramientas como el Agente GAUDI o el firmador libre. Hay que tener en cuenta que libidop11.so depende de otras librerías y ficheros de configuración y licencia, por lo que copiarla de manera individual para instalarla no es suficiente.

Si se quiere configurar en otras herramientas de manera unificada con p11-glue, se sugiere configurar un módulo de p11-kit para facilitar el descubrimiento de las ranuras (“slots”) la interfaz Cryptoki y de sus correspondientes fichas (“tokens”) como es el caso de la tarjeta. Una ruta relativamente común entre distribuciones suele ser /usr/share/p11-kit/modules/ donde se puede crear un fichero firma-digital.module que contenga la siguiente línea:

module: /usr/lib/SCMiddleware/libidop11.so

Si se va a habilitar firma digital en una máquina virtual con QEMU y KVM, hay que detener el servicio pcscd.socket en la máquina anfitrión (sudo systemctl stop pcscd.socket) antes de compartir el USB hacia la máquina virtual en caso de que el dispositivo aparezca como ocupado.

El componente fundamental que proporciona el distribuidor del controlador de tarjetas es de código cerrado y compilado únicamente para arquitectura x86_64. Si su computadora con GNU/Linux utiliza otro tipo de arquitectura diferente como ARM u otras, deberá utilizar algún tipo de emulación, por ejemplo, un contenedor en systemd-nspawn de arquitectura foránea con binfmt_misc y QEMU para no tener que emular una máquina completa.

19 comentarios en “Cómo instalar Firma Digital Certificada de Costa Rica en GNU/Linux

  1. Warner:

    Estimado Francisco: Gracias por colectar y revisar el problema que tuve con LMDE 7. Al respecto escribiste: se sugiere modificar el fichero /var/lib/dpkg/status y buscar agente-gaudi. En el apartado correspondiente hay que eliminar el “libpcre3, ” de la línea de dependencias” PREGUNTA: cómo modifico el fichero? intenté ingresar con Nautilus, pero no me permite el acceso. Soy travieso pero no informático. Serías tan amable de orientar a este pobre usuario?. Mil gracias como siempre sos un crack en Costa Rica y el mundo. Saludos desde Cartago

    1. Francisco de la Peña:

      con mucho gusto Warner. Para modificar ficheros que están fuera de su carpeta /home/usuario/ se requiere permisos de usuario administrativo. Para ello puede abrir la aplicación Terminal y teclear:
      sudo xed /var/lib/dpkg/status
      Le pedirá la contraseña. Tras ello, se abrirá el editor de texto que usa Linux Mint (se llama xed) y si aparece una franja roja que indica “Privilegios elevados”, ahora sí podrá modificar el fichero, de lo contrario estaría en modo solo lectura y no permitiría guardar cambios.
      Ahí puede buscar libpcre3 para ubicarse rápidamente y hacer el cambio.
      Saludos.

  2. Fernando Corrales:

    Buenos dias Fran, de antemano agradezco todas tus guias y ayuda. Acabo de instalar Ubuntu 24.04.3 LTS. Ya me funciona el GAUDI el ID Protect. Sin embargo cuando abro SICOP no me reconoce los certificados, me abre el cuadro de dialogo pero no ve los certificados.

      1. Fernando Corrales:

        Hola Fran, el mensaje que me da el cuadro de diálogo, es que no detecta tarjetas conectadas :/. Y ya no se que hacer

          1. Anónimo:

            Hola Fran, al final quite Ubuntu como tal e instala Linux Mint 22.1, pero curiosamente a la hora del lanzar el componente de firma con java 8 simplemente no se ejecuta. Trate correrlo directamente desde el terminal y me dice esto :
            fernando@fernando-ThinkCentre-M910t:~/Descargas$ 7z x ComponenteFirma_*.img

            7-Zip 23.01 (x64) : Copyright (c) 1999-2023 Igor Pavlov : 2023-06-20
            64-bit locale=es_CR.UTF-8 Threads:4 OPEN_MAX:1024

            Scanning the drive for archives:
            1 file, 324534272 bytes (310 MiB)

            Extracting archive: ComponenteFirma_3_0_18.img

            Path = ComponenteFirma_3_0_18.img
            Type = GPT
            Physical Size = 324534272
            ID = B313A395-AE10-4B43-9296-86CC205F7AFB
            —-
            Path = 0.disk image.hfsx
            Size = 324493312
            File System = HFS+
            Offset = 20480
            ID = B2DFF1CC-33D9-4D48-A053-024BAE3EDEC9

            Path = 0.disk image.hfsx
            Type = HFS
            Physical Size = 324493312
            Method = HFS+
            Cluster Size = 4096
            Free Space = 123305984
            Created = 2025-02-05 15:53:41
            Modified = 2025-02-05 15:53:42

            ERROR: Dangerous link path was ignored : Componente Firma/Applications : /Applications

            Sub items Errors: 1

            Archives with Errors: 1

            Sub items Errors: 1

            Y ahora si no tengo idea el porque de esto

            1. Fernando Corrales:

              Corrijo porque pegue erroneamente…
              ~/Descargas/Componente Firma/Componente_Firma.app/Contents/Java$ java -jar MerlinkSignMV.jar
              nov 23, 2025 10:09:13 PM main.MainProcess main
              GRAVE: null
              java.io.IOException: No existe el archivo o el directorio
              at java.io.UnixFileSystem.createFileExclusively(Native Method)
              at java.io.File.createNewFile(File.java:1023)
              at e.d.a.a(Unknown Source)
              at main.MainProcess.main(Unknown Source)

              1. Francisco de la Peña:

                Hola Fernando, ese error aparece cuando la carpeta Documents (no confundir con Documentos) no existe. Es un error absurdo de la aplicación, que espera que exista y si no existe falla con ese error. Se soluciona fácilmente, está explicado en la guía mencionada:
                mkdir $HOME/Documents
                Saludos,

                1. Fernando Corrales:

                  Hola Fran, correcto, ese era parte del problema, pero de nuevo me volvi a pegar en la parte cuando le das inicio de sesion, abre el cuadro de dialogo, pero da el mensaje de ¨no se han detectado tarjetas conectadas¨. Ahorita estoy con Mint, pero a ese punto llegue con Zorin OS y copn Ubuntu. No se que estare haciendo mal o si mas bien debo de hacer algo mas

                  1. Fernando Corrales:

                    Ya la firma en si si funciona para todo lo demas, es solo en SICOP donde esta la pega

                    1. Francisco de la Peña:

                      Sí, el MerlinkSignMV.jar del SICOP tiene sus particularidades, la principal es que parece que todavía requiere Java 8, probablemente no sirve 17, 21 o 25. En Mint puede hacer:
                      sudo apt install openjdk-8-jre
                      Y seleccionar el comando java por defecto mediante:
                      sudo update-alternatives --config java
                      Y ahí elige la versión 8 (o versión 1.8.0, que es lo mismo).

                    1. Anónimo:

                      En cuanto a la version si estoy corriendolo sobre Java 8
                      openjdk version “1.8.0_472”
                      OpenJDK Runtime Environment (build 1.8.0_472-8u472-ga-1~24.04-b08)
                      OpenJDK 64-Bit Server VM (build 25.472-b08, mixed mode)
                      Y en la consola no del navegador no aparece nada, estoy usando Chrome

                      En la terminal lo que me aparece es esto cada vez que le doy iniciar sesion:

                      java.io.IOException: /lib/x86_64-linux-gnu/libcrypto.so.3: version `OPENSSL_3.4.0′ not found (required by /usr/lib/SCMiddleware/libidop11.so)/usr/lib/SCMiddleware/libidop11.so
                      at sun.security.pkcs11.wrapper.PKCS11.connect(Native Method)
                      at sun.security.pkcs11.wrapper.PKCS11.(PKCS11.java:144)
                      at sun.security.pkcs11.wrapper.PKCS11$SynchronizedPKCS11.(PKCS11.java:1623)
                      at sun.security.pkcs11.wrapper.PKCS11.getInstance(PKCS11.java:159)
                      at services.core.device.model.b.b(Unknown Source)
                      at services.core.device.model.b.a(Unknown Source)
                      at controller.a.c(Unknown Source)
                      at controller.b.a(Unknown Source)
                      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
                      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
                      at java.lang.reflect.Method.invoke(Method.java:498)
                      at org.eclipse.jetty.websocket.common.events.annotated.CallableMethod.call(Unknown Source)
                      at org.eclipse.jetty.websocket.common.events.annotated.OptionalSessionCallableMethod.call(Unknown Source)
                      at org.eclipse.jetty.websocket.common.events.JettyAnnotatedEventDriver.onTextMessage(Unknown Source)
                      at org.eclipse.jetty.websocket.common.message.SimpleTextMessage.messageComplete(Unknown Source)
                      at org.eclipse.jetty.websocket.common.events.AbstractEventDriver.appendMessage(Unknown Source)
                      at org.eclipse.jetty.websocket.common.events.JettyAnnotatedEventDriver.onTextFrame(Unknown Source)
                      at org.eclipse.jetty.websocket.common.events.AbstractEventDriver.incomingFrame(Unknown Source)
                      at org.eclipse.jetty.websocket.common.WebSocketSession.incomingFrame(Unknown Source)
                      at org.eclipse.jetty.websocket.common.extensions.AbstractExtension.nextIncomingFrame(Unknown Source)
                      at org.eclipse.jetty.websocket.common.extensions.compress.PerMessageDeflateExtension.nextIncomingFrame(Unknown Source)
                      at org.eclipse.jetty.websocket.common.extensions.compress.CompressExtension.forwardIncoming(Unknown Source)
                      at org.eclipse.jetty.websocket.common.extensions.compress.PerMessageDeflateExtension.incomingFrame(Unknown Source)
                      at org.eclipse.jetty.websocket.common.extensions.ExtensionStack.incomingFrame(Unknown Source)
                      at org.eclipse.jetty.websocket.common.Parser.notifyFrame(Unknown Source)
                      at org.eclipse.jetty.websocket.common.Parser.parseSingleFrame(Unknown Source)
                      at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillable(Unknown Source)
                      at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillable(Unknown Source)
                      at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(Unknown Source)
                      at org.eclipse.jetty.io.FillInterest.fillable(Unknown Source)
                      at org.eclipse.jetty.io.ChannelEndPoint$1.run(Unknown Source)
                      at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(Unknown Source)
                      at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(Unknown Source)
                      at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(Unknown Source)
                      at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(Unknown Source)
                      at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(Unknown Source)
                      at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(Unknown Source)
                      at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(Unknown Source)
                      at java.lang.Thread.run(Thread.java:750)

                    2. Francisco de la Peña:

                      Gracias, ese error está muy interesante, algo está sucediendo con la versión de la librería.
                      ¿Podría mostrarme la salida de este par de comandos?

                      ldd /usr/lib/SCMiddleware/libidop11.so
                      ls -l /usr/lib/SCMiddleware/

                      Es curioso porque la librería incluye su propio libssl.so.3 pero por alguna razón no la está agarrando aparentemente.

  3. Fernando Corrales:

    linux-vdso.so.1 (0x00007ffd78dc3000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x000076381ca13000)
    libpcsclite.so.1 => /lib/x86_64-linux-gnu/libpcsclite.so.1 (0x000076381ca07000)
    libcrypto.so.3 => /usr/lib/SCMiddleware/libcrypto.so.3 (0x000076381c400000)
    libidolog.so => /usr/lib/SCMiddleware/libidolog.so (0x000076381c2b4000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x000076381ca02000)
    libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x000076381c000000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x000076381c9d2000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000076381bc00000)
    /lib64/ld-linux-x86-64.so.2 (0x000076381cc02000)
    libssl.so.3 => /usr/lib/SCMiddleware/libssl.so.3 (0x000076381bef8000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x000076381bb17000)
    fernando@fernando-ThinkCentre-M910t:~$ ls -l /usr/lib/SCMiddleware/
    total 20296
    -rwxr-xr-x 1 root root 1381904 sep 17 01:02 idocachesrv
    -rw-r–r– 1 root root 175704 sep 17 01:02 legacy.so
    -rw-r–r– 1 root root 6609760 sep 17 01:02 libcrypto.so.3
    -rw-r–r– 1 root root 1352496 sep 17 01:02 libidolog.so
    -rw-r–r– 1 root root 1914680 sep 17 01:02 libidop11.so
    -rw-r–r– 1 root root 1254288 sep 17 01:02 libssl.so.3
    -rw-r–r– 1 root root 4838072 sep 17 01:02 libt_ias.so
    -rwxr-xr-x 1 root root 3238248 sep 17 01:02 SCManager

    1. Francisco de la Peña:

      Gracias, sí está tomando la libssl.so.3 propia, por lo que está extraño.
      Los tamaños de las librerías son diferentes a las mías, quizás porque yo uso la versión RPM, que viene compilada con otra versión de compilador y con otros parámetros seguramente. De todos modos revisemos otras posibilidades:
      salida del comando:
      openssl version
      Por otra parte, sería bueno sasber si instaló el .deb de ubuntu 24.04 o si fue uno anterior. También si puede abrir la aplicación SCManager. Si la aplicación no se abriera, intente y aparecerá la ventana de notificación de tarjetas conectadas y vuelva a abrir SCManager. En la columna de iconos de la izquierda aparecerá un icono de interrogación, ahí indicará la versión. Por ejemplo la mía es la 6.23.44.0.

  4. Fernando Corrales:

    OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)
    Idopte
    Smart Card Middleware Desktop
    Versión 6.23.44.0

    Esta complicado esto Fran

    1. Francisco de la Peña:

      Gracias, la versión de openssl es la típica de Ubuntu 24.04, que en la que se basa Mint. Curiosamente, es más antigua que la API que espera la librería cuando se invoca desde Java, que está buscando una versión superior a la 3.4.0 y no está utilizando la que está en la carpeta, como si la aplicación no estuviera tomando la ruta local para buscar la otra carpeta.
      Sugiero desinstalar el paquete del smart card middleware (no sé cómo se llama) y descargar e instalar la versión para ubuntu 22.04 y ver si mejora la situación.

Responder a Francisco de la Peña

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *