sha512 como un token no necesario para iniciar sesión

4

Mi sitio tiene un sistema de suscripción de noticias. Cuando se actualiza un elemento, se envía un correo electrónico de notificación a todas las personas suscritas a ese elemento.

Puede cancelar / suscribirse a través de un formulario en la página de cada elemento.

Quería incluir un enlace directo para darse de baja en los correos electrónicos de notificación. Luego me di cuenta de que la gente podría cerrar sesión o ver el correo electrónico en una máquina diferente desde su inicio de sesión (no permitimos que los usuarios inicien sesión simultáneamente en diferentes máquinas), así que quería crear una función de cancelación de suscripción con un solo clic eso no requiere que alguien esté conectado.

Naturalmente, esto significaba un token (esperemos) único.

Mi solución de prueba es esta:

  1. cuando un usuario se suscribe a un elemento, se genera un token a través de sha512 en una cadena concatenada de varias cosas (nombre de usuario, fecha y hora, itemid, etc.)
  2. el enlace para cancelar la suscripción incluye la ID del elemento, el tipo de elemento y el token como parámetros GET
  3. si y solo si las tres cosas coinciden en una fila en la base de datos user_subscriptions , la fila se elimina, lo que termina la suscripción

Esto funciona, y sospecho que es adecuado para esta tarea no sensible a la seguridad de suscribirse y cancelar la suscripción a publicaciones de noticias.

Lo que me lleva a Security.SE es la pregunta más importante de ¿Qué tan seguro es un sistema de token para otras acciones?

sha512 produce un hash de 128 caracteres, además tendrías que identificar la ID y el tipo de acción que deseas realizar ...

    
pregunta Drew 06.02.2012 - 03:49
fuente

4 respuestas

3

Un problema de seguridad con su enfoque es que todo lo que está haciendo hash puede ser sospechoso. Como resultado, los tokens pueden ser adivinables.

Una solución simple es generar el token al azar: use una cadena aleatoria de 128 bits de una fuente criptográficamente aleatoria (por ejemplo, /dev/urandom o CryptGenRandom ) para formar un token de un solo uso. Almacene el token en la base de datos junto con información sobre la acción deseada, y cuando reciba una solicitud, si contiene un token encontrado en la base de datos, realice la acción sugerida por esa entrada de la base de datos y elimine el token. Si adopta este enfoque, no incluya nada como ID de artículo, tipo de elemento, etc., en la URL. En su lugar, guárdelo en la base de datos.

Como alternativa, puedes incluir algún secreto indiscutible (por ejemplo, una clave criptográfica de 128 bits) como parte de la entrada a la función hash. Cuando reciba la solicitud, deberá volver a calcular la función de hash (utilizando los parámetros de la solicitud) y asegurarse de que el token proporcionado sea correcto. Asegúrese de que todos los parámetros en la URL estén incluidos como parte de la entrada a la función hash (de lo contrario, alguien podría cambiar ese parámetro sin invalidar el token).

Como observa @AaronS, si alguien reenvía el correo electrónico, el destinatario del correo electrónico reenvía el token. Por lo tanto, este esquema no es perfecto. Para algunos usos (por ejemplo, cancelar la suscripción), puede ser lo suficientemente bueno. Para otros (por ejemplo, administrar el acceso a una cuenta bancaria en línea), no es una buena opción.

    
respondido por el D.W. 06.02.2012 - 08:23
fuente
3

Quiere un MAC . De eso se trata su hash personalizado: una forma de asegurarse de que la URL en la que el usuario hace clic es una URL "genuina" para ese usuario, es decir, una URL que su sistema produjo, no algo computado por alguien más. Esto conduce a dos soluciones:

  1. Produce un token aleatorio por usuario, y lo almacena en la tabla de usuarios. Al enviar un correo electrónico a un usuario, incluya la URL de "anular la suscripción" que incluye el token aleatorio y el nombre del elemento de destino (de la cual se anulará la suscripción del usuario). No se moleste en poner otra información en la URL, el token aleatorio es suficiente. En su servidor, mantiene un índice en la columna que contiene los tokens aleatorios, de modo que puede asignar fácilmente tokens a la ID de usuario. Cuando el servidor web recibe una solicitud de una URL con token, anule la suscripción del usuario.

    Esto funcionará siempre que produzcas tus tokens aleatorios con un PRNG criptográficamente fuerte (por ejemplo, /dev/urandom en un sistema Linux) y los hagas lo suficientemente grandes como para reducir la tasa de éxito de "intentos de suerte" a valores despreciablemente pequeños. 16 bytes deberían ser suficientes.

  2. Mantener una clave secreta del lado del servidor. Para calcular una URL de cancelación de suscripción para un elemento y un usuario, incluya en la URL tres elementos: el elemento de destino, la ID de usuario y una MAC calculada sobre los otros dos valores ( HMAC / SHA-256 estará bien para eso), usando la clave del servidor como clave MAC. Cuando el servidor web recibe una solicitud de cancelación de la suscripción, extraiga los elementos y vuelva a calcular el MAC: si coincide con el de la URL, continúe con la cancelación de la suscripción.

    En comparación con el método anterior, este no requiere almacenamiento adicional en la base de datos. Por otro lado, ahora tienes una clave para administrar; Esto puede ser un poco incómodo en algunas configuraciones, especialmente cuando hay varios servidores frontend.

Por supuesto , todo el concepto de la URL de cancelación de suscripción con un solo clic supone que los contenidos del correo electrónico son lo suficientemente confidenciales con respecto a lo que está en juego (ya que la cancelación de la suscripción a las noticias es un asunto bastante trivial , el correo electrónico "seguridad" es probablemente suficiente).

    
respondido por el Thomas Pornin 09.02.2013 - 16:52
fuente
1
  

cuando un usuario se suscribe a un elemento, se genera un token a través de sha512 en una cadena concatenada de varias cosas (nombre de usuario, fecha y hora, itemid, etc.)

Para asegurarte de que el cifrado sea sólido, utiliza un código de autenticación de mensaje bien aceptado, como HMAC -SHA para firmar el detalles, en lugar de un simple hash.

Además de la fecha y hora de caducidad, también podría considerar un número de secuencia específico del usuario que se actualice cada vez que un usuario cambie su contraseña, de modo que un cambio de contraseña invalide los tokens emitidos anteriormente.

Deberá asegurarse de que los datos firmados no cambien de significado. Por ejemplo, cualquier ID única no se reutiliza después de una eliminación, por lo que el elemento al que se hace referencia en un token no cambia. Además, si algún recurso tiene permisos mutables, deberá realizar la autorización en el momento de la generación y de la recepción, de modo que un token emitido para una acción no otorgue permiso a un usuario para llevar a cabo esa acción después de un cambio que eliminaría sus permisos.

  

¿Qué tan seguro es un sistema de token para otras acciones?

Una ficha firmada por HMAC de longitud adecuada es generalmente lo suficientemente apretada. La preocupación sería cómo distribuirlos, ya que el correo electrónico no es un canal maravillosamente seguro.

    
respondido por el bobince 06.02.2012 - 09:04
fuente
0

Las personas pueden reenviar su correo electrónico a sus amigos y luego un amigo puede hacer clic en el enlace. Entonces, especialmente si no cambias este hash para cada correo electrónico, no es realmente un secreto.

Si necesita "no repudio", esto no es una solución.

A

    
respondido por el AaronS 06.02.2012 - 07:07
fuente

Lea otras preguntas en las etiquetas