Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   PHP (https://www.clubdelphi.com/foros/forumdisplay.php?f=15)
-   -   Autenticación de dos factores (https://www.clubdelphi.com/foros/showthread.php?t=94476)

roman 27-02-2020 18:50:39

Autenticación de dos factores
 
1 Archivos Adjunto(s)
Hola a todos,

No sé si ya se ha hablado de esto aquí anteriormente, pero para desempolvar un poco la bodega pongo a su disposición un mecanismo para que puedan implementar la autenticación de dos factores en sus sitios web.

Para quienes desconozcan el asunto, resumo que ésta consiste en proporcionar un código de seguridad (generalmente de seis dígitos) además de los consabidos nombre de usuario y contraseña. El ejemplo, quizá más conocido es el de GMail. Cuando activamos la autenticación de dos factores y queremos ingresar a nuestra cuenta desde un dispositivo desconocido, Google nos requerirá, luego del usuario y contraseña, de un segundo paso (factor) para comprobar que realmente somos quienes decimos ser y no alguien que se robó nuestro username y password. Si nuestra cuenta de correo está asociada ya a nuestro móvil, el segundo factor puede ser simplemente el oprimir el botón "SÍ" que nos llega al dispositivo.

Pero también podemos hacer uso de un generador de códigos como el Google Authenticator del propio Google o cualquier otro como el de LastPass. Estos códigos corresponden al concepto de One Time Password, es decir, contraseñas de un sólo uso, que es precisamente lo que aumenta la seguridad de nuestra cuenta. Huelga decir que para hacer uso de esta funcionalidad, GMail nos pide primero dar de alta la cuenta en el autenticador. El código proporcionado por el autenticador tiene un tiempo de vida de 30 segundos.

Este código de seis dígitos:



se asocia a un servicio y usuario específicos, por lo que, como se ve en la imagen, distintas cuentas proporcionan distintos códigos.

Pues bien, la idea entonces es poder usar cualquiera de estos autenticadores en nuestras propias aplicaciones web.

A grosso modo a cada usuario de nuestro sistema se le proporciona un código numérico y un código QR:



que se escanea con el autenticador para dar de alta la cuenta o, si uno es masoquista, captura el código de 64 caracteres.

Cuando el usuario desee ingresar a nuestra aplicación, podemos pedirle, luego de su usuario y contraseña, el código de seis dígitos que en ese momento aparezca en el autenticador y que nosotros comprobaremos. Podemos hacer eso porque el código se genera básicamente con dos elementos:
  • El Unix Timestamp actual (o mejor dicho, el intervalo de 30 segundos más cercano) y
  • una llave secreta que conocemos nosotros y que se le pasa al autenticador al momento de escanear el código QR (por lo cual el código QR debe poseerlo únicamente el usuario calificado).

La llave secreta que se pasa al autenticador debería ser una combinación de una llave conocida sólo por nosotros y el nombre de usuario para que cada usuario reciba códigos de segundo factor distintos.

Para que el usuario reciba su QR sin riesgo a que revele a otros nuestra llave, ésta debe combinarse con su nombre de usuario de una forma no trivial, por ejemplo, usando la función hash_hmac de PHP:

Código PHP:

$llave hash_hmac('sha1''tribilin'"Mi súper llave secreta compartida"); 

Para que el autenticador acepta la llave, debemos codificarla en base 32, lo que nos dará justamente:

Código:

MZRDIZRQGI4TIYZTMY2WGMZRMQ4DQODDG43TKNRVGZTGIZRUMUYTCMRUMQ4TCNBW
como se muestra en la imagen.

Si se decodifica eso, sólo se verá:

Código:

fb4f0294c3f5c31d888c775656fdf4e1124d9146
que no revela la súper llave secreta.

En el archivo adjunto viene una carpeta oath con el código fuente de un ejemplo de verificación del segundo paso y la generación del código QR (usando el servicio de Google API Chart). Si disponen de un servidor local de desarrollo, deberían poder colocar la carpeta en su raíz web



escribir un nombre de usuario y escanear el código con el autenticador. A partir de entonces, en el segundo recuadro colocan el código del autenticador y presionan SEND para verificar.

Los archivos que dan vida a esto vienen en la carpeta oath/src y son tres:
  1. oauth.php
  2. gauth.php
  3. base32.php

Además viene el archivo hmac_sha1.php que no es necesario pero que les puede servir para ver cómo se implementa el hash_hmac que mencioné arriba.

El archivo oauth.php tiene varias funciones, pero la básica es totp (de Time based One Time Password). Esta función recibe como parámetro único la llave tal como se le envía al autenticador, ANTES de codificarla en base 32, y devuelve el código de seis dígitos que es el que compararíamos con el que nos proporcione el usuario en el segundo paso de la autenticación.

En el archivo gauth.php contiene la función gauth cuyos parámetros principales son:
  • $user nombre de usuario de la aplicación
  • $key La llave secreta que se le pasó al autenticador (sin codificar en BASE 32)
  • $issuer Nombre de la organización que emite la llave (lo escogemos nosotros)

Esta función devuelve un arreglo con dos valores:
  • src La url de la API Chart de Google que pondríamos en el atributo src de una etiqueta <img>
  • secret La llave secreta tal como se le pasa al autenticador (ya codificada en base 32)

El archivo base32.php contiene una versión light de codificación base 32 (es decir, light porque es apta sólo para textos relativamente pequeños). Hasta donde he visto, PHP no cuenta con funciones para este tipo de codificación.

Como es justo dar al César lo que es del César, menciono que la versión original de estas funciones las vi en https://github.com/Voronenko/PHPOTP pero decidí simplificarlas en el proceso de tratar de entender qué es lo que hacían.

Desde luego, no es necesario usar el servicio de Google para generar los QR. En el archivo gauth.php está la función getOtpAuthUrl que devuelve la cadena con la que debe conformarse el QR y podemos usar cualquier biblioteca que deseemos para tal efecto.

// Saludos

mamcx 27-02-2020 19:06:08

Un tip: El uso de google authenticator puede causar que se pierdan los logins en un formateo total del dispositivo (eso me paso!). Es mas recomendado usar authy.

Casimiro Notevi 27-02-2020 20:11:22

Cita:

Empezado por roman (Mensaje 535990)
...

^\||/^\||/^\||/

Ñuño Martínez 28-02-2020 11:22:13

Te has llevado un punto de reputación positiva. Muchas gracias por la explicación.

ElKurgan 28-02-2020 11:28:16

Gracias por el aporte, amigo Román

Un saludo

ecfisa 28-02-2020 14:59:49

Agradecido, como siempre Roman. :)

Saludos :)

Julián 09-03-2020 11:16:30

Cita:

Empezado por mamcx (Mensaje 535991)
Un tip: El uso de google authenticator puede causar que se pierdan los logins en un formateo total del dispositivo (eso me paso!). Es mas recomendado usar authy.

Exacto.

Ami me ha pasao esto y es una gran putada. Ya no quiero Google Authenticator ni en pintura.

Prefiero algo mas sencillo como que metes el user (o mas bien el email) y pass (incluso no haría falta la pass) y te llega un email con un link que al pulsarlo te permite entrar en la web.

Casimiro Notevi 09-03-2020 11:48:26

También perdí mis datos con google authenticator, lo malo es que en algunos sitios obligan a usarlo y no sirve otro.

roman 17-03-2020 21:51:50

Cita:

Empezado por Julián (Mensaje 536188)
Exacto.

Ami me ha pasao esto y es una gran putada. Ya no quiero Google Authenticator ni en pintura.

Prefiero algo mas sencillo como que metes el user (o mas bien el email) y pass (incluso no haría falta la pass) y te llega un email con un link que al pulsarlo te permite entrar en la web.

Wrong

Cita:

Empezado por Casimiro Notevi (Mensaje 536189)
También perdí mis datos con google authenticator, lo malo es que en algunos sitios obligan a usarlo y no sirve otro.

Wrong


Al parecer no leyeron bien. El Google Authenticator se puede usar como muchos otros. Todos los que se mencionaron aquí usan el mismo algoritmo así que no tiene ni sentido que alguien obligue a usar el de Google. Todos producen los mismos números.

Por otra parte se trata de no hacerle la vida difícil al usuario. Si le pides que acceda a su correo a ver el link ya es un paso más que deben dar. Además, un click a un sólo link es algo poco seguro, como ya en algún momento hice notar respecto de los manejadores de correos que visitan enlaces aun sin abrir el mensaje.

Saludos

mamcx 18-03-2020 00:27:48

Cita:

Empezado por roman (Mensaje 536308)
Wrong

No roman, el problema no es de algoritmo, es que LITERALMENTE se pierden los datos. Y si vieras lo "divertido" de recuperar 2-factores cuando tu app de 2-factores te elimino TODO.

Casimiro Notevi 18-03-2020 10:29:56

Eso es lo que me pasó, que abrí el google authenticator y habían desaparecido todos los datos, estaba como si acabara de instalar el programa.
Y por supuesto, ya no podía entrar en esos sitios a hacer nada, había que deshabilitar ese método, te piden varias semanas para validar la petición, etc.
Después probé con authy, y de momento va bien.

roman 18-03-2020 16:52:12

Sí, sí. Yo entiendo el problema. Pero es que tú comentaste que en algunos sitios obligan a usarlo y no sirve otro y eso es lo que yo digo que no es cierto. Tú puedes usar el que te guste y no pierda datos y, dado que el algoritmo es el mismo, no importa cuál uses.

Saludos

roman 18-03-2020 16:59:12

Cita:

Empezado por mamcx (Mensaje 536314)
No roman, el problema no es de algoritmo, es que LITERALMENTE se pierden los datos. Y si vieras lo "divertido" de recuperar 2-factores cuando tu app de 2-factores te elimino TODO.

Por eso, se pierden los datos en esa aplicación en particular. Solución: usa otra, como tú mismo mencionaste antes. Al no leer bien lo que se expone, se desvirtúa el contenido y ahora da la impresión de que el problema está con la autenticación de dos factores.

Saludos

Casimiro Notevi 18-03-2020 17:07:44

La lógica indica que tiene que ser así, pero por lo visto hay alguna diferencia que desconozco cuál es.
Instalé otro en lugar del de google y no me daba valores válidos para entrar en ciertos sitios, no me quedó más remedio que volver al de google.
Ni idea del motivo.

roman 18-03-2020 19:30:12

Cita:

Empezado por Casimiro Notevi (Mensaje 536337)
La lógica indica que tiene que ser así, pero por lo visto hay alguna diferencia que desconozco cuál es.
Instalé otro en lugar del de google y no me daba valores válidos para entrar en ciertos sitios, no me quedó más remedio que volver al de google.
Ni idea del motivo.

¿Recuerdas que aplicación era la otra?

Saludos

Casimiro Notevi 18-03-2020 19:48:47

Cita:

Empezado por roman (Mensaje 536342)
¿Recuerdas que aplicación era la otra?
Saludos

Sí, freeOTP

roman 19-03-2020 03:21:06

Es raro. Acabo de probar los dos freeOTP que vi en el Play Store y me dan los mismos números que el Google Authenticator. En uno de los dos programas parece que puedes escoger la codificación, que debes ser SHA1 y Base 32. Quizá por ahí hubo algo diferente.

Saludos

Casimiro Notevi 19-03-2020 10:36:09

Cita:

Empezado por roman (Mensaje 536349)
... puedes escoger la codificación, que debes ser SHA1 y Base 32. Quizá por ahí hubo algo diferente.

Tiene que ser eso, porque no es lógico que devolviera códigos distintos. Probaré a ver.


La franja horaria es GMT +2. Ahora son las 16:00:42.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi