Autenticación Web con el DNI Electrónico Peruano 

Desde hace ya mucho tiempo estuve detrás de lograr este objetivo, el poder hacer que mis usuarios por medio de su DNIe puedan logear a los aplicativos web usando su DNIe, realmente en internet existe muy poca información al respecto de como realizar esto, pero les voy a hacer un resumen para entender el funcionamiento antes de pasar a la nuestra implementación.

Como ya hemos hablado antes el DNIe tiene dos certificados dentro, uno de ellos que nos sirve para poder firmar electronicamente documentos,  y el otro que nos permite autenticarnos de manera remota, el que vamos a usar para poder lograr este objetivo es el segundo certificado.

Ahora como es el proceso, este certificado sirve para poder realizar una encriptación de dos vias, esto que significa, bueno espero que tengan claro que la diferencia de http y https sino van a estar perdidos, el https genera una capa adicional sobre el protocolo http encriptando la comunicación entre los puntos por medio de un certificado SSL, de esta manera el cliente que se conecta al sitio web puede verificar la identidad del sitio que esta visitando, ahora la autentificación de dos vias significa que de la misma manera que el servidor encripta la comunicación para mandarsela al cliente, el cliente haciendo uso del certificado del DNIe encripta la comunicación de regreso, bueno eso es lo que pasa en resumidas cuentas, ya que existe lo que es una negociación entre el cliente y el servidor para poder lograr esto.

Ahora de la misma manera que nuestro cliente verifica las credenciales del servidor (verificando los certificados de confianza del sistema) el mismo proceso debe de realizar el servidor para verificar los certificados que tiene el cliente, validando entre otras cosas, si este certificado se encuentra vigente, si no se encuentra revocado, y si la cadena de confianza es conforme, en nuestro caso “Perú” nuestro emisor de certificados no se encuentra dentro de los certificados raíz de ningún sistema operativo ni mucho menos de servidores, por lo que se tiene que echar mucha más programación en el lado del servidor, para entrar en especial a la parte de validación del certificado ya que a partir del 01 Julio del 2017 ya los nuevos certificados son emitidos con el algoritmo SHA256 (High Grade).

Ahora siendo sinceros,  tengo varias aplicaciones web y en diferentes dominios, la verdad la necesidad de invertir en certificados SSL en cada uno de los servidores realmente se sale del presupuesto, pero la ventaja de tener la autentificación por medio del DNIe realmente vale la pena en especial para evitar tanto ataque de fuerza bruta que tenemos en nuestros servidores que nos terminan bloqueando las cuentas por intentos fallidos.

Al Grano  

Para esto ya debes de tener tu DNIe funcionando si aún no lo tienes date una vuelta primero por acá

Bueno como vieron no se va necesitar que adquieran un certificado SSL, para poder hacer la autentificación, más o menos he replicado el funcionamiento de tokens que trabajan muchas aplicaciones como Facebook, Google, etc, asi que si ya trabajaste con estos medios de autentificación la tendrás fácil.

El secreto esta que desde tu aplicación web realices una llamada a un servicio web ubicado en https://ehg.pe/auth/dnie/  en esta dirección ese servidor va a negociar directamente con el cliente para la validación del certificado de su DNIe, el secreto es que tu realices la llamada a esta dirección desde tu aplicación web desde cualquier medio, incluso desde un iframe oculto puede funcionar, lo que te va a devolver es un JSON con la información de tu DNI Electrónico acompañado de un campo que es TOKEN, que es una cadena de caracteres aleatoria, que después vas a poder ingresar desde tu servidor para poder confirmar su valides, este es un ejemplo del JSON que envia el servidor:

{
   "SERIAL" : "XXXXXXXXXXXXXXXX",
   "DN_O" : "Registro Nacional de Identificación y Estado Civil",
   "DN_C" : "PE",
   "DN_OU" : "RENIEC Certification Authority",
   "ORIGIN" : "DIRECT",
   "IP" : "164.XXX.XXX.XXX",
   "DN_S" : "PAREDES CORNEJO",
   "DN_G" : "Julio Guillermo",
   "VERIFY" : "SUCCESS",
   "DN_ST" : "Arequipa",
   "RFC4523" : "{ serialNumber XXXXXXXXXXX, issuer rdnSequence:\"serialNumber=RUC: 20295613620,CN=RENIEC Class II High Grade CA,OU=RENIEC Certification Authority,O=Registro Nacional de Identificaci\\C3\\B3n y Estado Civil,C=PE\" }",
   "REMAIN" : "708",
   "SERIAL_B10" : "XXXXXXXXXXXXXX",
   "TOKEN" : "foT8+q0Vvz5QOfsfM58ROJIeUos",
   "END" : "Dec 30 14:24:13 2017 GMT",
   "DN" : "CN=PAREDES CORNEJO Julio Guillermo (AUTYYYYYYYY),serialNumber=DNI:XXXXXXXX,GN=Julio Guillermo,SN=PAREDES CORNEJO,L=Cayma,ST=Arequipa,C=PE",
   "SIG" : "sha256WithRSAEncryption",
   "KEY" : "rsaEncryption",
   "VERSION" : "3",
   "DN_CN" : "PAREDES CORNEJO Julio Guillermo (AUTYYYYYYYY)",
   "START" : "Dec 30 14:24:13 2015 GMT",
   "DN_L" : "Cayma",
   "DNI" : "YYYYYYYY"
}

Una vez que desde tu aplicación web pueda recibir esta información podrás convertir en objeto desde el json, y poder tratar la información sin ningún problema, acá adjunto un ejemplo que desarrolle en Angular2 para que lo descarges , y que esta publicado y en funcionamiento en http://gparedes.ehg.pe/apps/dnie/   en esta aplicación realiza el proceso que esto mencionando anteriormente.

Ahora te preguntaras para que es el Token, bueno la verdad es sencilla ese token es la credencial que va a poder indicarte si la sesión AÚN es valida, remarco esto porque es posible que el DNIe electrónico se logee desde otra terminal lo que haria que todos los token pasados simplemente se deshabiliten, para esto tenemos un segundo metodo, para poder ver si un Token aun sige estando vigente, y es por medio de la dirección: https://ehg.pe/auth/? seguida por el token que se quiere consultar en el caso de este ejemplo seria asi https://ehg.pe/auth/?foT8+q0Vvz5QOfsfM58ROJIeUos y nos dara una respuesta similar a esta:

{
   "expired" : 0,
   "data" : "YYYYYYYY",
   "ip" : "164.XXX.XXX.XXX",
   "token_type" : "SmartCard",
   "time_create" : "2017-12-22 19:40:44.064129",
   "origin" : "http://gparedes.ehg.pe/apps/dnie/",
   "token" : "foT8+q0Vvz5QOfsfM58ROJIeUos",
   "time_lastseen" : "2017-12-22 21:41:08.021154"
}

en caso de un token no valido o expirado enviara algo asi:

{
   "expired" : 1,
   "token" : "foT8+q0Vvz5QOfsfM58ROJIeUoss"
}

Ahora si se dieron cuenta ofusque mi información personal por seguridad pero donde encuentren YYYYYYY es el número de DNI, y donde esta el XXXXXX es información referente al serie electrónica del DNIe.

Me olvidaba de indicar que un Token en caso que no se use en 60 minutos se inhabilita de manera automática, eso significa que la sesión expira si pasa ese tiempo sin uso.

Ahora ojo, esta segunda llamada es para que lo realices de preferencia desde tu servidor y no desde tu vista web, esto con el objetivo de evitar un ataque de hombre en el medio, de esta manera cada vez que hagan una llamada a tu servidor, dentro de tu servidor valida si el token es valido o no, y procede a responder o no la petición.

Notas Varias

Ya lo he probado en Chrome en Windows, Mac y Linux con el aplicativo que esta http://gparedes.ehg.pe/auth/dnie, pero este programa tiene problemas con Safari y Firefox, me parece que como esta hecho en Angular que google por ahí no esta bien definido el tema de la autentificacion de dos vias, ya genere los reportes respectivos, es cosa de esperar que lo arreglen en los navegadores,

Por otro lado cuando he hecho las llamadas desde aplicaciones hechas con Flash Builder (Antes conocido como Flex) realmente me funciono en todas las plataformas y navegadores, (imagino porque al tener la capa intermedia de Flash Player hace transparente esto). es una pena que ya lo vayan a descontinuar 🙁

Este proceso te ayudara a poder autentificar al usuario con DNIe dentro de tu aplicación pero no va a encriptar la información entre tu aplicación y el cliente.

 

6 Replies to “Autenticación Web con el DNI Electrónico Peruano”

  1. Me funciona de maravilla, pero me gustaria saber si existe la posibilidad de que puedas hacer el mismo procedimiento pero que en vez de json devuelva un codigo javascript declarando el objeto, asi puedo incorporarlo en mi pagina web con la etiqueta y despues pueda trabajarlo como una variable global. He realizado intentos y asi funciona en todos los navegadores en windows (solo me pide la contraseña del dnie y atravez de un trace veo que regresa la info) solo falta interpretarlo con el formato js que te pido se solucionaria, gracias

  2. Gracias, excelente aporte, cómo mencionas estás usando autenticación mutua(two-way authentication) mi consulta es en el lado del servidor (https://ehg.pe/auth/dnie/) que usaste java, PHP? y sobre el servidor de aplicaciones? Y si pudieras compartir las fuentes. Saludos.

Deja un comentario

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