Use sal como identificador para la identificación de sesión encriptada en el sistema de autenticación basado en bases de datos para webapp

2

He escrito un marco de autenticación basado en base de datos para aplicaciones web que planeo programar en el futuro.

El marco se implementa utilizando el lenguaje plpgsql de una base de datos PostgreSQL y, por lo tanto, la extensión pgcrypto se usa para cifrar información confidencial.

Si el usuario de una aplicación web se autentica (por lo que el servidor web activa algo), como

select authenticate('[email protected]', 'login-token')

devuelve la base de datos

False, Invalid user / login token

o

True, Successfully logged in, session-id

El identificador de sesión se transmite al servidor web en texto claro, por lo que se puede crear una cookie, mientras se guarda en la base de datos mediante la aplicación de un algoritmo de hashing, que viene con la extensión pgcrypto. Este es un tipo de implementación de bcrypt (la documentación de PostgreSQL es un tanto vaga). El id de sesión se combina con un salt único (uno por id de sesión).

Así que en la tabla de sesión encuentras algo. como

|primary key|user-id|bcrypt(session-id)|other information

La pregunta es sobre la función que se usa para verificar si el id de sesión es válido y de qué usuario se trata. Esta función se activa cuando el usuario presenta un ID de sesión al servidor web, que a su vez validará este ID de sesión.

select get_user_by_session_id(session-id)

Si no hay un identificador adicional, la parte de selección tiene el siguiente problema:

Para cada fila en la tabla de sesión, la función hash debe aplicarse a la identificación de sesión dada.

Esto funciona como

  • seleccione una fila de la tabla de sesión
  • lee el salt y hash el identificador de sesión dado por el usuario
  • compare el resultado con el hash de la fila real
  • repita hasta que encuentre una coincidencia (devuelva Verdadero) o llegue al final de la tabla sin ninguna coincidencia (devuelva Falso)

Esto es un poco lento (más lento si hay más sesiones).

Entonces, la idea es usar un identificador, que no es sensible a hacer lo siguiente (pseudocódigo)

  • seleccione get_user_by_session_id (usuario-dado-dentificador, session_id)
  • seleccione el hash de la tabla de sesión donde identifier = user-given-identifier
  • compruebe si hash_function (session_id) = hash

Esto tiene la ventaja de que solo se necesita una operación criptográfica, en lugar de una para cada fila en la tabla de sesión hasta que se encuentre la válida.

En el diseño actual, hay dos identificadores posibles que le puedo dar al usuario.

  • Una clave de miembro única estática que se genera en el registro para cada usuario.
  • La sal utilizada para cifrar / hash el id de sesión

Iría por la sal, porque quería usar el member_key para fines de identificación (llamadas de soporte) o algo más. No veo ningún problema con esto, debido a las siguientes razones:

  • en general, la sal no debe estar encriptada y se puede guardar en texto sin formato
  • solo el servidor web y el usuario mismo ven la sal (servidor web durante la transmisión, usuario en la cookie)
  • el atacante solo puede obtener esta sal interceptando la conexión; si lo hace, también obtiene el identificador de sesión en texto sin formato

¿Echo de menos algo? ¿Tiene la variable miembro_clave estática alguna ventaja sobre la sal?

    
pregunta Markus 17.10.2015 - 19:12
fuente

1 respuesta

0

Reemplazé la clave principal de la tabla de usuarios con un uuid en lugar de una serie grande y lo utilicé como información insensible.

El identificador de sesión en el cliente se ve como ||.

Con esto pude minimizar la búsqueda de sesión desde > 1 segundo a unos 100 ms.

    
respondido por el Markus 08.11.2015 - 14:14
fuente

Lea otras preguntas en las etiquetas