Firmar desde tu aplicación web con el certificado del usuario: por qué el navegador no llega al certificado y qué arquitecturas quedan
Imagina un portal de proveedores con un botón «Firmar» junto a cada PDF. El equipo de desarrollo abre la documentación de la Web Cryptography API, busca cómo pedirle al navegador el certificado que el usuario tiene en su token o en su DNIe, y no lo encuentra. No es que falte una función: el estándar dice que ese acceso no es asunto suyo. Lo que queda es elegir dónde se hace la firma, y de esa elección dependen qué sale del navegador, qué ve el usuario y si la firma sigue siendo del usuario o pasa a ser de la empresa.
Lo que el estándar del navegador deja fuera
La Web Cryptography API es una Recomendación del W3C del 26 de enero de 2017. Su sección 4.3, «Out of scope», dice que la API «does not specifically address the provisioning of keys in particular types of key storage, such as secure elements or smart cards», y añade que «does not deal with or address the discovery of cryptographic modules». Traducido: el estándar no define cómo una página encuentra un módulo criptográfico ni cómo usa las claves privadas que hay dentro de una tarjeta.
Comprobé el mismo texto en el borrador de trabajo de nivel 2 (22 de abril de 2025), al que hoy redirige la dirección w3.org/TR/WebCryptoAPI/. Es una lectura del estándar, no una prueba con cada navegador: no probé si alguno ofrece por su cuenta un puente hacia tarjetas. Lo que sí se desprende del texto es que ningún estándar te asegura que la página pueda listar los certificados de un token, así que un diseño que dependa de eso descansa en algo que nadie prometió.
Por eso toda la firma con certificado del usuario en una web acaba usando un programa fuera del navegador, o moviendo la clave privada a otro sitio. Son las tres arquitecturas que siguen.
Primera: un componente local que la web invoca
La web no firma. Llama a un programa instalado en el equipo del usuario, y ese programa habla con el token, con el DNIe o con el almacén de certificados del sistema. En Perú hay dos ejemplos oficiales.
Firma Perú. Es la Plataforma Nacional de Firma Digital, creada por el artículo 91.1 del D.S. 029-2021-PCM (El Peruano, 19 de febrero de 2021) como la plataforma «que permite la creación y validación de firmas digitales dentro del marco de la IOFE». La Secretaría de Gobierno y Transformación Digital aprobó su guía de uso e integración con la Resolución 002-2022-PCM/SGTD, fechada el 22 de septiembre de 2022 y publicada el 24. El documento de integración web tiene control de versiones hasta la 4.0.0 (marzo de 2025), aunque el pie de página aún dice 3.0.0.
El flujo, según ese documento, es este:
- Tu página carga
firmaperu.min.jsdesdeapps.firmaperu.gob.pey llama astartSignature(port, param). El puerto que recomienda es el 48596, para levantar un servidor local enhttp://localhost:port. parames un JSON en Base64 con una URL de tu servidor, un token de un solo uso y la extensión del documento.- El componente local llama a esa URL y recibe los parámetros de firma: formato (PAdES para PDF, XAdES, CAdES), nivel (B, T o LTA), la URL del documento y la URL a la que devolverá el resultado.
- Descarga el documento en el equipo del usuario, lo firma y lo sube por POST a tu servidor como
signed_file.
Lo que sale del navegador es poco: un token y una dirección. Lo que viaja es el documento completo, primero de tu servidor al equipo del usuario y luego de vuelta ya firmado. El hash, en cambio, no pasa por tu servidor. Según la guía, el aplicativo «obtiene el hash del documento y lo envía al módulo criptográfico», que «solicita al firmante su PIN o contraseña» y devuelve la firma. La clave privada no se mueve del token.
El usuario ve dos cosas que tu web no controla: la selección del certificado y el PIN, y en PAdES el visor donde coloca la representación gráfica de la firma. Tu web puede filtrar qué certificados aparecen con una expresión regular sobre el CN (certificateFilter), por ejemplo para que solo salgan los de firma.
ReFirma, de RENIEC. La página de ReFirma Suite dice que «ReFirma PDF puede ser invocado desde cualquier aplicacion web mediante el componente ReFirma Invoker». Indica que requiere Windows 7 a 11, y que el instalador ClickOnce descarga Java JRE 8 en la primera ejecución si no lo encuentra; la variante Java Web Start exige Java 8 ya instalado.
Este camino tiene fricciones que conviene poner en el presupuesto, todas de la propia documentación de Firma Perú:
- En Windows exige .NET Framework 4.8 y un plugin ClickOnce en el navegador. La guía admite que Google Chrome «ha descontinuado el soporte para la mayoría de las extensiones ClickOnce» y recomienda Microsoft Edge, que lo admite de forma nativa.
- En Ubuntu y macOS solo funciona con DNIe, no con certificados instalados, y necesita Java 8 (con IcedTea-Web en Linux, OpenWebStart en macOS). En Linux, solo con Firefox.
- Si el antivirus o el cortafuegos bloquean
http://localhost:puerto/firmaperu/sign, el servicio no arranca. Es el primer sitio donde mirar cuando un usuario dice que «no pasa nada».
Y una limitación de alcance, que empieza en la propia norma: el artículo 91.1 crea Firma Perú «para la provisión de los servicios digitales prestados por las entidades de la Administración Pública». La guía y el procedimiento de credenciales (firmaperu@pcm.gob.pe, con correo institucional del responsable de tecnologías) están escritos para entidades de la Administración Pública. No encontré ningún documento oficial que diga que una empresa privada pueda obtener esas credenciales, así que no lo afirmo. Si no eres entidad pública, pregunta antes de diseñar sobre esto.
Segunda: el certificado del usuario vive en el HSM de un prestador
Aquí el usuario no tiene un token. Su clave privada está en el HSM de un prestador y autoriza cada firma desde su cuenta. La norma lo define en el artículo 35 c) del D.S. 052-2008-PCM, en el texto que dejó el D.S. 029-2021-PCM: el «sistema de creación de firma remota» es el que «permite efectuar operaciones de creación de firma digital utilizando claves privadas que se encuentran localizadas remotamente y son gestionadas por un tercero».
Lo que sale de tu servidor y cómo se autoriza cada firma está en Tu sistema firma con un certificado que está en la nube, y no lo repito. Lo que añade este ángulo es qué ve el usuario y qué dice la norma. El usuario no instala nada, pero sí sale de tu pantalla o recibe una petición de autorización del prestador, con el segundo factor que este exija. Y la norma cubre el caso: el artículo 8 a), tal como lo modificó el mismo decreto, presume que el suscriptor «tiene el control de la clave privada asociada, con un elevado grado de confianza, incluso cuando la misma es gestionada por un Prestador de Servicios de Valor Añadido acreditado en la modalidad de sistema de creación de firma remota».
Ese «acreditado» pesa. Si el prestador no lo está, la presunción no se apoya en ese texto. Cómo comprobarlo lo explica el pilar del clúster y lo matiza la comparación con el token.
Una consecuencia práctica: el certificado remoto es otro certificado. El artículo 10 b) le da al suscriptor dos opciones: «Generar por sí mismo la clave privada, o autorizar su generación a distancia» por el prestador acreditado. En firma remota la clave privada se genera en el HSM, así que un usuario con un token de otro emisor no puede traerlo a este flujo. Tendrá que emitir uno nuevo.
Tercera: la firma se hace en tu servidor con un certificado de la organización
Es la más cómoda de programar: tu servidor firma con una clave privada que tú custodias, sin componente local ni pantalla de PIN. La guía de Firma Perú la describe como «Creación de firma digital de agente automatizado de manera integrada a un flujo documental»: el sistema de información «envía el documento al servicio de creación de firma digital de agente automatizado», que obtiene el hash y lo firma. Aquí sí sale el documento completo, hacia el servicio que firma.
Pero ya no es la firma del usuario. La misma guía cita el glosario del reglamento: si el certificado es de agente automatizado, «la titularidad del certificado y de las firmas digitales generadas a partir de dicho certificado corresponderá a la persona jurídica». El artículo 16 c) del reglamento, en su versión de 2021, pide para este certificado la razón social, el RUC y el «nombre del sistema de información o sistema de cómputo»: ningún nombre de persona. Sirve para que la organización firme lo que emite (constancias, reportes, comprobantes donde se acepte), no para que Ana Rojas firme su contrato. Si tu requisito es que firme Ana, esta arquitectura no lo cumple, aunque el PDF salga con una firma válida. Cuándo un certificado de agente automatizado no sirve ni siquiera para SUNAT está en otro artículo.
El atajo peligroso es un cuarto camino que no es arquitectura sino error: pedir al usuario su archivo de certificado y su contraseña, y firmar con ellos en el servidor. Técnicamente es la tercera opción con la identidad de la primera. Jurídicamente, el artículo 10 c) obliga al suscriptor a «mantener el control y la reserva de la clave privada bajo su responsabilidad», y los artículos 6 y 8 exigen una firma creada por medios que el firmante mantiene «bajo su control». Entregar su clave privada a tu servidor es lo que esas frases quieren evitar. Es mi lectura, no una interpretación de INDECOPI, pero no la pondría a prueba en una controversia sobre autoría.
Qué sale del navegador y qué ve el usuario
| Componente local | Firma remota | Certificado de la organización | |
|---|---|---|---|
| Del navegador al componente o proveedor | Token de un solo uso y URL | Redirección o petición de autorización | Nada del usuario |
| Documento | Baja al equipo del usuario y vuelve firmado | Depende de la API, ver el artículo enlazado | Va al servicio que firma |
| Dónde está la clave privada | Token, DNIe o almacén del sistema | HSM del prestador | Módulo de la organización |
| El usuario ve | Selector de certificado y PIN | Autorización en el prestador | Nada |
| De quién es la firma | Del usuario | Del usuario | De la persona jurídica |
Cuál elegir
Mi criterio, defendible pero opinable: si el usuario debe firmar personalmente y ya tiene token o DNIe, y tu entidad puede integrarse con Firma Perú o ReFirma, la primera. Pide a cambio asumir el soporte de instalación, que es donde se va el tiempo. Si los usuarios son muchos, no tienen token o firman desde el celular, la segunda evita instalar nada, con la condición de que el prestador esté acreditado. La tercera solo cuando quien firma es la organización, y se dice así en el documento.
Para certificados de persona natural, jurídica o de agente automatizado, están en la página de certificados, y si dudas de qué arquitectura te toca puedes escribirnos. El marco general de qué exige la ley al integrar está en la guía completa.
Lo que este artículo no afirma
- No afirmo que ningún navegador pueda acceder a un token por medios propios: leí lo que dice el estándar, no probé cada navegador.
- No afirmo que una empresa privada pueda obtener las credenciales de Firma Perú o de ReFirma Invoker; los documentos que leí se dirigen a entidades públicas.
- No doy versiones de Java ni de .NET más allá de las que citan los documentos oficiales, y esos documentos pueden haber cambiado.
- No comparo productos comerciales de firma en la web: no verifiqué sus características.
- La lectura sobre entregar el certificado del usuario al servidor es mía, no de la autoridad.
Fuentes de esta página
- W3C, Web Cryptography API, Recomendación del 26-ene-2017, sección 4.3.
- D.S. 029-2021-PCM, El Peruano, 19-feb-2021: artículo 91, y modificaciones a los artículos 6, 8, 10, 16 y 35 del D.S. 052-2008-PCM.
- Resolución 002-2022-PCM/SGTD, El Peruano, 24-sep-2022, y su guía en PDF.
- Firma Perú, documento de integración web.
- RENIEC, ReFirma PDF.