¿Qué transferir? Contraseña o su hash?

36

Digamos que en mi base de datos almaceno las contraseñas con sal con un hash bastante caro (scrypt, 1000 rondas de SHA2, lo que sea).

Al iniciar sesión, ¿qué debo transferir a través de la red y por qué? Contraseña o su hash?

¿Es posible proteger dicho inicio de sesión en un canal no cifrado como HTTP?

    
pregunta Konrad Garus 30.06.2011 - 14:47
fuente

4 respuestas

57

Si transfiere el hash desde el cliente, esto no ofrece ningún beneficio de seguridad y hace que el hash no tenga sentido:
Si un usuario puede iniciar sesión enviando el hash al servidor, entonces el hash es efectivamente la contraseña.

    
respondido por el AviD 30.06.2011 - 14:54
fuente
21

Si su protocolo de autenticación consiste en enviar al servidor una contraseña, o un hash de la contraseña, con HTTP simple, entonces esto es inherentemente muy débil, por dos razones:

  • Alguien que espía en la línea podría registrar lo que el cliente envía. Si solo enviar estos bytes otorga acceso, entonces el atacante podría simplemente enviarlos nuevamente. Eso es un ataque de repetición . Este problema es lo que alude @AviD en su respuesta. Ninguna cantidad de hash arreglará eso. Algunos protocolos intentan corregir este problema incluyendo un "desafío" del servidor (un valor aleatorio, creado de nuevo para cada conexión), que se debe incluir junto con la contraseña en el cliente; de eso se trata la autenticación del Compendio HTTP .

  • Incluso si la autenticación funcionó, esto sigue siendo HTTP simple, por lo que cualquier información que se envíe después será vulnerable a las escuchas y alteraciones de los atacantes. Si el medio de transporte no está protegido, la autenticación disuadirá solo a los atacantes más sofisticados. Aquí es donde falla el Compendio HTTP.

Por lo tanto, realmente necesita SSL (también conocido como HTTPS), no solo para transmitir su contraseña o hash, sino también el resto de la conversación entre el cliente y el servidor.

En lo sucesivo, asumo que el protocolo se ejecuta dentro de un túnel SSL. Tienes razón al querer usar un hash lento como bcrypt o PBKDF2; tenga en cuenta que también se necesita un salt para evitar el costo compartido (por ejemplo, tablas precomputadas). El hashing lento y salado se utiliza para hacer frente a la debilidad intrínseca de las contraseñas. Ahora, es posible que desee descargar parte del esfuerzo de hash en el cliente. Este puede funcionar, pero plantea algunos problemas prácticos:

  • Dado que el procesamiento de la contraseña debe incluir un salt, uno nuevo para cada instancia de contraseña, entonces el salt debe transmitirse al cliente, de modo que el cliente pueda incluirlo en el hashing que realiza. Esto aumenta la complejidad del protocolo: el cliente primero debe enviar el nombre de usuario al servidor, luego el servidor debe devolver el salt y, solo entonces, el cliente puede comenzar a codificar la contraseña. Este es un viaje de ida y vuelta más a la red que con el habitual "enviar nombre de usuario y contraseña como una solicitud POST".

  • El hashing lento consiste en aceptar gastar una gran cantidad de CPU en cada contraseña, de modo que el atacante también tiene que gastar una gran cantidad de CPU en cada contraseña. Pero si la CPU gastada está en el cliente, no podemos aumentarla tanto como nos gustaría, porque: 1) hay clientes que tienen muy poca CPU (por ejemplo, algunos teléfonos inteligentes o tabletas baratos) y 2) el contexto web implica usar Javascript, y el rendimiento de Javascript es realmente malo cuando se trata de hash (digamos, al menos 20 veces más lento que el código C).

Por lo tanto, lo más habitual es que vale la pena hacer parte del hashing de contraseñas en el cliente.

    
respondido por el Thomas Pornin 28.10.2012 - 16:54
fuente
4

Ambas opciones son inseguras.

La transferencia de la contraseña hará que su protocolo sea de texto simple. Transferir el hash, te hará vulnerable a los ataques de repetición.

APOP es una implementación de inicio de sesión para el protocolo POP. Esto permite que el protocolo mantenga la contraseña privada de cualquier oyente en la red. Un inconveniente de esto es que tanto el cliente como el servidor necesitan conocer la contraseña en texto sin formato, ya que este es el secreto compartido. Antes del protocolo, tanto el cliente como el servidor tienen < contraseña > La comunicación del protocolo es básicamente así:

  1. El cliente se conecta al servidor y envía un token aleatorio (T1)
  2. El servidor envía un token aleatorio (T2)
  3. El cliente envía M = sha (T1 + T2 + < contraseña: copia del cliente >) al servidor
  4. El servidor comprueba si sha (T1 + T2 + < contraseña: copia del servidor >) coincide con M (el hash que se acaba de recibir).

Aquí, el servidor conoce tanto la magia como la contraseña, y puede determinar si el usuario conoce la contraseña correcta sin exponerla a ningún oyente.

La mejor práctica sería almacenar de forma segura los hash en la base de datos y confiar en canales cifrados.

    
respondido por el Dog eat cat world 30.06.2011 - 14:58
fuente
-1

Ninguno, idealmente, uno usa un mecanismo de respuesta de desafío y luego transfiere ese hash, y hace todo esto a través de un canal criptográficamente seguro como SSL. Pero a la mayoría de los usuarios no les gusta tomar solo 5 minutos para iniciar sesión. Además, el usuario debería revisar todo esto antes de usarlo.

En última instancia, depende de la cantidad de seguridad que uno necesita y de los vectores de ataque de los que uno trata de protegerse, pero usar SSL siempre es una buena idea.

    
respondido por el ewanm89 01.07.2011 - 22:12
fuente

Lea otras preguntas en las etiquetas