¿Es mejor hash n * x veces en sha1 o n veces en sha512 en el lado del cliente?

6

Ya sé que voy a cifrar la contraseña del usuario n veces en sha512 o n * x en sha1 antes de enviarla al servidor. Una vez en el servidor, usaré bcrypt set para usar ~ La centésima de segundo. Antes de continuar, en mi razonamiento detrás de usar sha512 en lugar de sha1, me gustaría mencionar algunas cosas. Primero, sé que la seguridad del lado del cliente es una broma. Segundo, sé que un ataque Man-in-the-middle podría eliminar el javascript de la página de la función hash. Por último, me doy cuenta de que esto significará que las personas no podrán iniciar sesión sin habilitar el javascript.

Actualmente estoy usando sha512 set para usar ~ 1s en ie8 [2], está configurado como tal.

  1. Toma la contraseña y el nombre de usuario del usuario.
  2. Agrega una fuente estática (para alargarla realmente y nada más).
  3. Hash a través de la función de hashing, en este caso sha512.
  4. Toma ese hash, hazlo a través de sha512 con el número de bucle actual empaquetado en un solo byte.
  5. repite el paso 4 n veces.
  6. Una vez que haya terminado, tome ese valor y colóquelo en el campo de contraseña.
  7. finalmente, permita que el sistema POST al servidor.

Ahora bien, ¿cuál es la ventaja de hacer n * x hashes de sha1 frente a las n veces de sha512? El punto detrás del uso de este sistema es que, en el caso de que se produzca una fuga en la base de datos, el atacante tendrá que aumentar la cantidad de tiempo dedicado a tratar de encontrar la contraseña por tiempo. Además, al incluir el hash antes de que llegue al servidor (junto con el uso de TLS), lo hace, de modo que, en el caso de algún error extraño, la contraseña nunca se ve como texto simple.

Creo que sha512 es una mejor opción ya que sha1 ya está roto y, por lo tanto, su seguridad no vale la pena, sino por el otro lado. La biblioteca javascript más rápida que he encontrado para sha512 [1] [] es ~ 50 veces más lenta que el código nativo, pero la biblioteca sha1 más rápida que he encontrado es solo ~ 17 veces más lenta que el código nativo.

Por lo tanto, se trata de si el sha1 roto va a causar una mayor pérdida en la seguridad general y, por lo tanto, la desaceleración de un atacante que hacer menos iteraciones de sha512, que a partir de ahora no se ha roto ninguna de las familias de sha2. ¿Alguien más ha tratado este tema antes?

[1]: el hecho de fuzzing da como resultado el mismo hash que la implementación de c / php, da como resultado el mismo hash para ~ 300 entradas.

[2]: un año después de que se elimine ie10, me gustaría dejar el soporte para ie8 para poder aumentar el número de hashes a algo más razonable.

    
pregunta 133794m3r 13.07.2011 - 00:47
fuente

2 respuestas

9

Esto suena un poco exagerado, quizás contraproducente, no es óptimo y realmente no ofrece mucha seguridad adicional. La "contraseña" se ve realmente en texto sin formato, porque la contraseña es la cadena que finalmente envía en lugar de la contraseña real. ¿Qué es exactamente lo que estás tratando de lograr?

De cualquier manera, si realmente está intentando que la "contraseña 'real' no se vea en texto claro '(y no confíe en ssl), debería estar implementando un protocolo de desafío-respuesta. Esta suele ser la forma en que se hace si no quiere que la contraseña se transporte de forma clara (o algo parecido a la contraseña como en su caso).

Ahora, si realmente desea continuar con su plan, y aún así hacer los trucos del lado del cliente que describe, SHA-1 está perfectamente bien para eso. Incluso MD5 está bien y considerablemente más rápido. La 'charla en la calle' acerca de las funciones que no son seguras es sobre colisiones, que es algo que probablemente no le importe en su implementación. También puede consultar enlace , es una biblioteca jquery que realiza el cifrado asimétrico de formularios html.

Pero, nuevamente, desaconsejo esta implementación en su totalidad.

    
respondido por el john 13.07.2011 - 03:50
fuente
9

La protección adicional agregada por el hash del lado del cliente es extremadamente marginal. Desde el punto de vista del servidor, el resultado de hash es la contraseña, porque el servidor otorga acceso a quien sea capaz de mostrar ese valor de hash, sin requerir la contraseña real. En particular, si un "error extraño" hace que el valor del hash sea evidente para el atacante, entonces usted pierde: el atacante simplemente puede conectarse al servidor mostrándole el valor del hash, sin ejecutar su Javascript (el usuario promedio puede tener problemas para evitar un poco de Javascript, pero no sería seguro asumir que el atacante no es un poco más capaz).

La protección que queda es que si el atacante solo ve el hash, aún no ha adivinado la "contraseña real" y no podrá (inmediatamente) probar esa contraseña en otros servidores Donde el mismo usuario también tiene una cuenta. Esto no cambia nada a la seguridad de su servidor, pero podría verse como un "servicio comunitario".

En cuanto al costo de ataque adicional inducido por el hashing múltiple: aunque la idea es sólida, el uso de Javascript no lo es. Javascript es mucho más lento que C o ensamblador. Toma un segundo con IE8 en Javascript, pero nada obliga al atacante a ejecutar su ataque en Javascript. Puede usar C, ensamble, posiblemente una GPU. Si desea dificultar los ataques de diccionario, debe hacer que el hash lento para el atacante . Al hacerlo en el cliente en Javascript, se evita realizar tantas iteraciones como sean necesarias para lograr la seguridad adecuada. Una forma de verlo es la siguiente: queremos que cada "conjetura" sea lenta para el atacante. Desafortunadamente, no podemos hacerlo lento para el atacante a menos que también lo sea para el "sistema honesto". Por lo tanto, el rendimiento de los sistemas honestos (cliente y / o servidor) limita la cantidad de lentitud que podemos inyectar. Al hacerlo en el cliente en un lenguaje subóptimo, hacemos que la carga de la lentitud sea mucho más pesada para los sistemas honestos y no para el atacante.

En la práctica, el costo del ataque será el de bcrypt; El hashing será insignificante en comparación. Esto es especialmente cierto para SHA-512, que utiliza operaciones de enteros de 64 bits, que son muy lentas de implementar en Javascript, debido a la falta de tipos de enteros de 64 bits. Entonces, la respuesta precisa a tu pregunta es: usar SHA-1 (o SHA-256) sería "mejor" que SHA-512 si el objetivo es inducir lentitud a los ataques de diccionario; pero aún así, la lentitud inducida será despreciable con respecto a lo que hace bcrypt del lado del servidor, por lo que la pregunta no tiene sentido. Por otro lado, el retraso adicional de 1s enfurecerá a los usuarios normales, que se sabe que no tienen paciencia.

    
respondido por el Thomas Pornin 13.07.2011 - 14:19
fuente

Lea otras preguntas en las etiquetas