Qué hashing / encriptación usar para la cadena compartida públicamente que coincide con un código secreto

1

Estoy buscando la forma sin base de datos de cómo validar un código secreto que fue enviado al teléfono móvil del usuario mediante la aplicación web RESTful, en un proceso de autenticación de 2 factores.

En el paso 1, el usuario proporciona el nombre de inicio de sesión y la contraseña que se validan con los datos de la base de datos. Ahora el sistema genera un código que se envía al teléfono móvil del usuario. Para mayor comodidad, el código debe ser relativamente simple, digamos 5 dígitos numéricos. El usuario debe proporcionar este código para completar el proceso de autenticación.

Me gustaría evitar los viajes a la base de datos tanto como sea posible, así que uso JWT para mantener el estado. Pero sería absurdo almacenar el código de autenticación secreto en el JWT, porque se puede extraer fácilmente en el lado del cliente. Por lo tanto, debe ser almacenado en forma de hash o cifrado. Estoy considerando compartir el código secreto con sal fuerte (conocido solo por el servidor) y luego almacenar el hash SHA256 del resultado (el hash bcrypt no es bueno aquí porque contiene la sal). Eso haría que el código secreto quedara oculto a cualquier mirada indiscreta, pero aún así sería útil para validar el código cuando lo proporciona alguien que lo conoce. Y el servidor puede olvidar el código mientras tanto.

¿Puede este enfoque considerarse seguro para el propósito dado?

    
pregunta Passiday 12.03.2017 - 16:18
fuente

2 respuestas

1

Está buscando códigos de autenticación de mensajes, no puros hash. Probablemente podrías hacer algo como lo siguiente:

El servidor genera un código. También guarda un secreto (eso es básicamente lo que quisiste decir con tu sal secreta). Luego calcula

mac = hmac-sha256(code, secret)

mac se almacena en su jwt. Cuando el usuario ingresa su código, el servidor lo usa y secret solo el servidor sabe calcular mac2 , y si mac2 coincide con mac , el usuario ingresó el código correcto.

Editar: Has señalado correctamente que esto puede ser explotado porque el mismo código siempre produce el mismo mac. Para que pueda corregir este problema de la siguiente manera:

mac = hmac-sha256(code || salt, secret)

Ahora tienes que almacenar salt junto con mac en tu jwt. Elija un nuevo salt aleatorio cada vez que genere un nuevo mac. Creo que la construcción anterior es segura, pero es posible que desee buscar un poco en Google para asegurarse.

HMAC es un protocolo que se utiliza para generar códigos de autenticación de mensajes (macs), consulte Wikipedia para obtener más información. La mayoría de los lenguajes de programación ofrecen una biblioteca para trabajar con HMAC.

    
respondido por el Pascal 12.03.2017 - 17:16
fuente
0

Tengo problemas para ver cómo funciona esto de alguna manera, por favor, tenga paciencia conmigo.

Estamos tratando con un segundo factor de autenticación, así que trabajemos con el supuesto de que en realidad es necesario; en otras palabras, el primer factor ha sido comprometido.

Esto es lo que hago como hacker.

  1. Configuré mi propia cuenta
  2. Me conecto a tu aplicación
  3. Recibo un código 2FA y JWT que se sala y firma según lo sugerido. Ahora tengo un JWT y el código que lo acompaña.
  4. Ahora intento iniciar sesión en SU cuenta con sus credenciales comprometidas
  5. El sistema le envía el código 2FA a USTED, por lo que realmente no lo recibo, y no tengo idea de cuál es el código.
  6. Todavía tengo el JWT y el código del paso 3, así que lo uso.

¿Cómo es esto seguro de alguna manera? Tiene que haber algo que vincule el código al usuario.

    
respondido por el John Wu 12.03.2017 - 23:03
fuente

Lea otras preguntas en las etiquetas