Contraseñas de aplicaciones web: bcrypt y SHA256 (y scrypt)

Con todas las discusiones recientes (por ejemplo, en LinkedIn) de contraseñas, estoy buscando implementaciones de hash de contraseñas. Después de dos tazas de café y una mañana leyendo, no soy más criptógrafo que cuando empecé. Y realmente no quiero fingir que lo soy.

Preguntás especificas

¿El uso de un ID de usuario único de entero falla como un salt efectivo? (crypt () usa solo 16 bits?)

Si simplemente ejecuto sha256 () en un hash una y otra vez hasta que se agote un segundo, ¿eso derrota los ataques de fuerza bruta?

Si tengo que hacer estas preguntas, ¿debería usar bcrypt?

Discusión / Explicación:

El objetivo es simplemente si las contraseñas de hash de mi usuario se filtraron:

no sería "fácil" de romper,descifrar una contraseña no expondría a otros usuarios que usen la misma contraseña).

Lo que he leído para el número 1 es que el cálculo de hash debe ser costoso: tomar, por ejemplo, uno o dos segundos para calcular y tal vez requerir un bit o memoria (para frustrar el descifrado del hardware).

bcrypt tiene esto incorporado, y scrypt, si lo entiendo correctamente, está más preparado para el futuro e incluye un requisito mínimo de uso de memoria.

Pero, ¿es un enfoque igualmente efectivo para comer tiempo al "repetir" el resultado de sha256 () tantas veces como sea necesario para usar unos pocos segundos y luego almacenar el conteo final del bucle con el hash para verificar posteriormente la contraseña proporcionada?

Para el # 2, es importante usar una sal única para cada contraseña. Lo que no está claro es cuán aleatoria (o grande) debe ser la sal. Si el objetivo es evitar que todos los que usen "mypassword" como contraseña tengan el mismo hash, ¿no es suficiente con esto?

hash = sha256_hex( unique_user_id + user_supplied_password );

O incluso esto, aunque no estoy seguro de que me compre algo:

hash = sha256_hex( sha256( unique_user_id ) + user_supplied_password );

El único beneficio que puedo ver al usar la identificación del usuario, además de que es único, es evitar tener que guardar la sal junto con el hash. No es una gran ventaja. ¿Existe un problema real con el uso de la ID de un usuario como la sal? ¿No logra el # 2?

Supongo que si alguien puede robar las contraseñas con hash de mi usuario, debo asumir que pueden obtener lo que quieran, incluido el código fuente que genera el hash. Entonces, ¿hay algún beneficio al agregar una cadena aleatoria adicional (la misma cadena) a la contraseña antes de hacer hash? Es decir:

# app_wide_string = one-time generated, random 64 7-bit *character* string.
hash = sha256_hex( unique_user_id + app_wide_string + user_supplied_password );

He visto eso sugerido, pero no entiendo lo que gano con eso por la sal por usuario. Si alguien quisiera forzar el ataque con fuerza bruta, sabrían que "app_wide_string" y lo usarían para ejecutar su ataque de diccionario, ¿verdad?

¿Hay alguna buena razón para usar bcrypt sobre mi propia versión como se describe anteriormente? Tal vez el hecho de que estoy haciendo estas preguntas es razón suficiente?

BTW: Acabo de programar una función de hash existente que tengo en mi computadora portátil y puedo generar unos 7000 hashes por segundo. No son exactamente los uno o dos segundos que se sugieren a menudo.

Algunos enlaces relacionados:

usando sha256 como hash y salado con ID de usuario

SHA512 contra Blowfish y Bcrypt

¿Cuál es la longitud óptima para la contraseña de usuario salt?

Respuestas a la pregunta(2)

Su respuesta a la pregunta