Elegir un algoritmo de ID de sesión para una relación cliente-servidor

22

Estoy desarrollando una aplicación que tiene una relación cliente-servidor, y tengo problemas para decidir el algoritmo por el cual se determina el identificador de sesión. Mi objetivo es impedir que los impostores adquieran los datos privados de otros usuarios.

Estoy considerando dos opciones:

Opción 1: genere una cadena hexadecimal aleatoria de 32 caracteres, almacénela en una base de datos y pásela del servidor al cliente una vez que haya iniciado sesión correctamente. Luego, el cliente almacena este identificador y lo usa en cualquier solicitud futura al servidor, lo que lo compararía con el identificador almacenado.

Opción 2: cree un hash a partir de una combinación de la hora de inicio de la sesión y el nombre de usuario de inicio de sesión del cliente y / o la contraseña con hash y úsela para todas las futuras solicitudes al servidor. El hash de la sesión se almacenaría en una base de datos a partir de la primera solicitud y se verificará para cualquier solicitud futura del cliente.

Otra información: Se pueden conectar varios clientes simultáneamente desde la misma IP, y no hay dos clientes que tengan el mismo identificador de sesión.

Pregunta: ¿Cuál de estas opciones es un mejor enfoque con respecto a mis preocupaciones (a continuación) sobre cada una?

Mi preocupación sobre la primera opción es que el identificador es completamente aleatorio y, por lo tanto, podría ser replicado por casualidad (aunque es un 1 en una posibilidad 3.4 * 10 38 ) , y se utiliza para "robar" datos privados de un usuario (que también necesitarían estar usando el cliente en ese momento).

Mi preocupación con respecto a la segunda opción es que tiene una falla de seguridad, a saber, que si se intercepta de alguna manera la contraseña con hash de un usuario, se podría falsificar todo el hash de la sesión y robar los datos privados del usuario.

Gracias por todas y cada una de las entradas.

    
pregunta Vulcan 02.12.2012 - 21:49
fuente

3 respuestas

26

El concepto básico de un identificador de sesión es que es un nombre secreto de corta duración para la sesión , una relación dinámica que está bajo el control del servidor (es decir, bajo el control de su código). ). Depende de usted decidir cuándo comienzan y terminan las sesiones. Las dos características de seguridad de un algoritmo de generación de identificador de sesión exitoso son:

  1. No hay dos sesiones distintas que tengan el mismo identificador, con una probabilidad abrumadora.
  2. No debería ser computacionalmente factible "golpear" un identificador de sesión cuando se intentan aleatorios, con una probabilidad no despreciable.

Estas dos propiedades se logran con un ID de sesión aleatorio de al menos, digamos, 16 bytes (32 caracteres con representación hexadecimal), siempre que el generador sea un PRNG criptográficamente fuerte ( /dev/urandom en sistemas similares a Unix, CryptGenRandom() en Windows / Win32, RNGCryptoServiceProvider en .NET ...). Como también almacena el ID de sesión en el lado del servidor de la base de datos, podría buscar duplicados y, de hecho, su base de datos probablemente lo haga por usted (deseará que este ID sea una clave de índice), pero eso sigue siendo tiempo perdido porque la probabilidad es muy baja. Considere que cada vez que sale de su casa, está apostando a la idea de que no se verá afectado por un rayo. Matarse por un rayo tiene una probabilidad de aproximadamente 3 * 10 -10 por día ( realmente ) . Eso es un riesgo que amenaza la vida , su propia vida, para ser precisos. Y sin embargo, descartas ese riesgo, sin siquiera pensar en ello. ¿Qué sentido tiene, entonces, preocuparse por las colisiones de ID de sesión que son millones de veces menos probables y que no matarían a nadie si ocurrieran?

No tiene mucho sentido lanzar una función hash adicional en la cosa. La aleatoriedad aplicada correctamente ya le dará toda la singularidad que necesita. La complejidad agregada solo puede dar como resultado debilidades adicionales.

Las funciones criptográficas son relevantes en un escenario en el que no solo desea tener una sesión, sino que también desea evitar cualquier costo de almacenamiento basado en el servidor; Por ejemplo, no tiene ninguna base de datos en el servidor. Este tipo de descarga de estado requiere un MAC y posiblemente el cifrado (consulte esta respuesta para algunos detalles).

    
respondido por el Thomas Pornin 02.12.2012 - 23:57
fuente
5

Los identificadores de sesión deben ser criptográficos, aleatorios y únicos. Si un atacante puede adivinar una ID de sesión legítima, puede hacerse pasar por ese usuario.

La opción 1 es su mejor apuesta, siempre que use un CSPRNG adecuado, y no algo como rand() de una biblioteca estándar. Usar algo como la opción 2 no es tan seguro, ya que los nombres de usuario y los tiempos son fáciles de adivinar o de fuerza bruta.

Eche un vistazo a cómo código del generador de ID de sesión de PHP funciona, y verá que se utiliza una función hash para combinar la dirección IP del cliente, la hora actual (segundos y microsegundos) y algunos valores del RNG del generador de congruencia lineal (LGC) de PHP como base. Si hay disponible una fuente aleatoria específica del sistema operativo, se mezcla más entropía en la ID de esa función. Esto da un margen de seguridad razonable si no hay una fuente de entropía fuerte disponible, pero proporciona una seguridad sólida si la hay.

    
respondido por el Polynomial 03.12.2012 - 00:01
fuente
1

Los identificadores de sesión deben estar firmados, entonces no tiene que preocuparse por las personas que intentan adivinar el ID de sesión.

También revisa las colisiones para asegurarte de que no hayas entregado ese identificador ya.

    
respondido por el Anthony Chris Zboralski 18.04.2013 - 14:50
fuente

Lea otras preguntas en las etiquetas