Token de verificación de autenticación basada en tiempo

5

Estoy creando un sistema de sesión de larga duración que requiere que los usuarios verifiquen su autenticación antes de realizar operaciones "peligrosas", como cambiar la configuración crítica, eliminar su cuenta, etc. Este requisito es análogo a Facebook que requiere que vuelvas a ingresar su contraseña antes de cambiar su dirección de correo electrónico, por ejemplo. Me gustaría permitir que el usuario realice cambios peligrosos dentro de un período de tiempo T después de verificar su contraseña.

El sistema se escalará horizontalmente, por lo que recordar "quién validó cuándo" en la memoria no es posible y me gustaría evitar almacenar la información en la base de datos, y buscarla en cada acción "peligrosa". Creo que eso deja la generación de algunos token seguros sensibles al tiempo como mi mejor alternativa.

Este es mi enfoque para generar y verificar este token. Por favor, avíseme si cree que he pasado por alto algo o si estoy cometiendo un error de seguridad tonto. Toda la comunicación cliente-servidor se realiza a través de TLS / SSL.

1. Alice wants to perform some "dangerous" operation (client side).
2. Alice is presented with a "verify password" modal or similar UI element
   where she enters her password.
3. The client-side system sends the password to the server.
4. The server checks if the password matches Alice's stored password.
5. If the passwords match, a token is generated as follows:
   a. Let 'id' be Alice's user ID (UUID), 't' be a fixed length 
      string representation of the current timestamp, and 'secret' 
      be a secret key appropriately protected on the server.
   b. Generate the secure part as 'k = (string) HMAC(secret, id + t)' 
      (Assume 'k' to be typecasted or converted to a string representation.)
   c. Finally, let 'token = k + t' where '+' is the string concatenation
      operator 
6. Send the token to Alice.
7. For each "dangerous" operation, Alice includes 'token' with the request. 
8. The server can verify the 'token' by splitting 'k' and 't' and
   validating 'k' as in step 5.b above, and verify that time 'T' hasn't
   elapsed since Alice verified her password.

Creo que este enfoque resuelve el problema. Sugerencias? ¿Me estoy perdiendo algo?

    
pregunta Joshua Toenyes 17.06.2016 - 18:41
fuente

2 respuestas

3

Yo sugeriría hacer t una marca de tiempo de precisión reducida en su lugar, donde se establece la precisión en la mitad de la precisión deseada. La razón de esto es evitar el envío de más datos que los necesarios para el cliente, lo que aumenta la seguridad, pero también, para poder filtrar los datos en el lado del servidor de manera más eficaz, para evitar ataques que surjan de riesgos. entrada contaminada.

Por ejemplo, si quieres que el token esté vivo durante 10 minutos, debes crear una marca de tiempo que cambie bruscamente una vez cada 5 minutos.

Usando una marca de tiempo estándar de Unix, divida esto con la mitad de segundos que desea que esté vivo el token y elimine el decimal.

Así que 1466182513, que es la hora actual. Divídelo con 300 (5 minutos) y int (). Obtienes: 4887275

que será válido desde:

Viernes, 17 de junio de 2016 16:55:00 GMT

a

Viernes, 17 de junio de 2016 16:59:59 GMT

Este valor decimal se puede incluir en el hash. Por lo tanto, el valor 4887275 es efectivamente un "reloj" que "marca" cada 5 'minuto.

Ahora al truco: Cuando verifica el hash, "intenta" tanto con el valor de precisión reducida para el tiempo ACTUAL, como con el valor de precisión reducida inmediatamente antes de esto. Esto significa efectivamente que el cliente podrá realizar "acciones sensibles" en cualquier lugar entre 5 y 10 minutos desde el momento en que ingresan la contraseña.

No malinterpretes esto ahora. Lo que quiero decir es que el token caducará entre 5 y 10 minutos a partir de la emisión, y este vencimiento dependerá de cuándo, en el período de tiempo, ingresen la contraseña.

Por ejemplo, en el ejemplo anterior, intenta validar el hash tanto con el valor 4887275, que es de la hora actual, como con el valor 4887274, que es el valor de hace aproximadamente 1-5 minutos.

Por supuesto, puede dividir con otros valores para obtener otra precisión, por ejemplo, 600 para obtener una validez de entre 10 a 20 minutos.

La razón por la que debe probar también la marca de tiempo inmediatamente anterior, es que, digamos que una persona ingrese su contraseña el viernes, 17 de junio de 2016 16:54:59. Ahora tiene 1 segundo para llevar a cabo su acción sensible, a menos que también probemos el valor inmediatamente antes. Esa es la razón por la que debe seleccionar un valor mitad de la precisión deseada.

Esto significa que no necesita enviar la marca de hora al cliente. Simplemente envíe el hash, ya que puede reconstruir fácilmente TODOS los datos del hash.

Una buena idea también es incluir el ID de sesión en el hash, por lo que el token se invalida de manera efectiva tan pronto como el usuario cierra la sesión o la sesión se destruye por algún otro motivo. También es una buena idea incluir el hash de la contraseña, por lo que si el usuario cambia su contraseña, cualquier token se volverá inválido.

    
respondido por el sebastian nielsen 17.06.2016 - 19:09
fuente
0

Kerberos es un protocolo efectivo que puede usarse para hacer esto. Los detalles se pueden encontrar aquí: enlace . Sin embargo, requiere un poco de configuración.

Es un método de autenticación y autorización sensible al tiempo. Básicamente, obtiene un Ticket-Granting-Ticket del servidor de autenticación, y eso se presenta al Ticket-Granting-Service para obtener un ticket que se puede usar para obtener la autorización para un servicio específico. Cuando ese servicio se presenta con el ticket, autoriza al usuario a realizar cualquier servicio que el servidor proporcione por el ticket. Si el boleto ha caducado, debe obtener un nuevo boleto del TGS.

Se puede solicitar al TGS que verifique la contraseña del usuario antes de proporcionar el ticket que autoriza al usuario a realizar dichos cambios. Cuando el ticket expire, el usuario deberá volver a autenticarse para obtener un nuevo ticket.

    
respondido por el Desthro 17.06.2016 - 19:14
fuente

Lea otras preguntas en las etiquetas