En general, no necesita usar más de un algoritmo de hash.
Lo que debes hacer es:
Use salt: la sal no se usa solo para hacer que su contraseña sea más segura , sino que se usa para abordar el ataque de la mesa arcoiris. De esa manera, alguien tendrá un trabajo más duro tratando de calcular previamente el hash para las contraseñas que almacene en su sistema.
Use múltiples interacciones: en lugar de hacer solo SHA (contraseña + sal), haga SHA (SHA (SHA (SHA (SHA (... SHA (contraseña + sal))))))). O, para representar de otra manera:
hash = sha(password + salt)
for i=1 , i=5000, i++ {
hash = sha(hash + salt);
}
Y, finalmente, elija una buena función de hashing. SHA, MD5, etc., no son buenos porque son demasiado rápidos . Como desea usar hash para protección, es mejor que use hash más lentos. Echar un vistazo a Bcrypt , PBKDF2 o Scrypt , por ejemplo.
editar : después de las observaciones, intentemos ver algunos puntos (perdón, explicación larga para llegar al final, porque podría ayudar a otros a buscar respuestas similares):
Si su sistema es seguro, como si nunca nadie tuviera acceso a la contraseña almacenada, no necesitaría hash. La contraseña sería secreta, nadie la obtendría.
Pero nadie puede asegurar que la base de datos con las contraseñas sea robada. Robar la base de datos, obtuve todas las contraseñas. Ok, su sistema y su empresa sufrirán todas las consecuencias del mismo. Por lo tanto, podríamos tratar de evitar esta filtración de contraseña.
AVISO de que no estamos preocupados por los ataques en línea en este punto. Para un ataque en línea, la mejor solución es reducir la velocidad después de contraseñas incorrectas, bloquear la cuenta después de algunos intentos, etc. Y para eso no importa de qué manera cifre, cifre, almacene, etc., su contraseña. El ataque en línea es una cuestión de ralentizar las entradas de contraseña .
Entonces, volviendo al don't let them take my plain passwords
problema. La respuesta es simple: no los almacene como texto sin formato. Ok lo tengo.
¿Cómo evitar eso?
Cifre la contraseña (?). Pero, como sabe, si lo encripta, puede volver a desencriptarlo, si tiene la clave adecuada. Y terminará con el problema de "dónde esconder" la clave. Hum, no está bien, ya que obtuvieron tu base de datos, pueden obtener tu clave. Ok, no lo usemos.
Entonces, otro enfoque: transformemos la contraseña en otra cosa que no se pueda revertir y almacénela. Y para verificar si la contraseña provista es correcta, hacemos el mismo proceso nuevamente y verificamos si los dos valores transformados coinciden. Si coinciden = se proporcionó la buena contraseña.
Ok, hasta ahora todo bien. Usemos un hash MD5 en la contraseña. Pero ... si alguien tiene nuestro valor hash almacenado de contraseña, puede tener mucha potencia de computadora para calcular el hash MD5 de cada contraseña posible (fuerza bruta), para que pueda encontrar la contraseña original. O, lo que es peor, puede almacenar todos los MD5 de todas las combinaciones de caracteres y encontrar fácilmente la contraseña. Entonces, haz muchas iteraciones, lo que es HASH (HASH (HASH ())), para hacerlo más difícil, porque tomará más tiempo.
Pero incluso eso se puede evitar, la mesa arcoiris fue creada exactamente para acelerar contra este tipo de protección.
Entonces, usemos un poco de sal sobre él. De esta manera, en cada interacción, la sal se usa nuevamente. Quien intente atacar sus contraseñas tendrá que generar la tabla del arco iris teniendo en cuenta que la sal se agrega cada vez. Y cuando genera esa tabla de arcoíris, ya que se generó con una sal, tendrá que calcular nuevamente con la otra sal, por lo que tendrá que pasar un tiempo para cada contraseña (= cada sal). Salt no agregará "más complejidad" a la contraseña, solo hará que el atacante pierda tiempo generando la tabla del arco iris, si usa una sal para cada contraseña, la tabla de una sal es inútil para otra contraseña.
¿Y usar más de un hash habrá ayudado aquí? No. La persona que genera un ataque de arco iris específico podrá generarlo usando uno o más hashes, de todos modos.
Y usar más de un hash puede llevarlo a un problema: es tan seguro como el hash más débil que usa. Si alguien encuentra colisiones en un algoritmo hash, es ese hash el que se explotará, en cualquier punto del proceso de iteración, para romper la contraseña. Entonces, no ganas nada usando más algoritmos hash, es mejor elegir solo un buen algoritmo. y úsalo. Y si alguna vez escucha que se ha roto, piense cómo lo cambiará en su aplicación.
Y por qué usar bcrypt o algo así (usted dice que lo usa): porque el atacante tendrá que pasar más tiempo generando las tablas. Es por eso que usar MD5 + wait (3 segundos) no ayuda: el ataque estará fuera de línea, de todos modos, por lo que el atacante puede generar las tablas sin el (retraso de 3 segundos).
MD5(password)
. Dijimos que no es seguro, por lo que sugirieron usar en suMD5(MD5(password))
lugar ...