He leído algunas veces que al almacenar contraseñas, es una buena práctica 'doble hash' de las cadenas (por ejemplo, con md5 y luego sha1, ambas con sales, obviamente).
Supongo que la primera pregunta es, "¿es esto realmente correcto?" Si no es así, por favor, descarte el resto de esta pregunta :)
La razón por la que pregunto es que, a primera vista, diría que esto tiene sentido. Sin embargo, cuando lo pienso, cada vez que se vuelve a agregar un hash (posiblemente con algo agregado), todo lo que puedo ver es que hay una reducción en el límite superior de la 'singularidad' final ... ese límite está relacionado con La entrada inicial.
Permítanme decirlo de otra manera: tenemos x número de cadenas que, cuando se procesan, se reducen a y posibles cadenas. Es decir, hay colisiones en el primer set. Ahora, desde el segundo conjunto hasta el tercero, ¿no es posible que ocurra lo mismo (es decir, colisiones en el conjunto de todas las cadenas 'y' posibles que resultan en el mismo hash en el tercer conjunto)?
En mi cabeza, todo lo que veo es un 'embudo' para cada llamada de función hash, 'canalizando' un conjunto infinito de posibilidades en un conjunto finito y así sucesivamente, pero obviamente cada llamada está trabajando en el conjunto finito anterior, dándonos un establecer no más grande que la entrada.
¿Quizás un ejemplo explicará mis divagaciones? Tome 'hash_function_a' que le dará a 'a' y 'b' el hash '1', y le dará a 'c' y 'd' el hash '2'. Usando esta función para almacenar contraseñas, incluso si la contraseña es 'a', podría usar la contraseña 'b'.
Tome 'hash_function_b' que le dará a '1' y '2' el hash '3'. Si tuviera que utilizar que como un 'hash de secundaria' después 'hash_function_a' a continuación, incluso si la contraseña es 'a' que podría utilizar 'b', 'c' o 'd'.
Además de todo eso, entiendo que se deben usar sales, pero en realidad no cambian el hecho de que cada vez que estamos asignando entradas 'x' a salidas 'menores que x'. No pienso
¿Puede alguien explicarme qué es lo que me falta aquí?
¡Gracias!
EDITAR: por lo que vale, no hago esto yo mismo, uso bcrypt. Y no estoy realmente preocupado sobre si es útil o no para 'usar ciclos' para un 'hacker'. Realmente me pregunto si el proceso reduce o no la "seguridad" desde un punto de vista de colisión hash.
MD5(password)
. Dijimos que no es seguro, por lo que sugirieron usar en suMD5(MD5(password))
lugar ...Respuestas:
Esto es más adecuado en security.stackexchange pero ...
El problema con
es que esto es tan fuerte como la función hash más débil de la cadena. Por ejemplo, si el hashn (el hash más interno) produce una colisión, toda la cadena de hash generará una colisión ( independientemente de los otros hash de la cadena ).
Una cadena más fuerte sería
Aquí evitamos el problema de colisión temprana y esencialmente generamos una sal que depende de la contraseña para el hash final.
Y si un paso en la cadena choca, no importa porque en el siguiente paso la contraseña se usa nuevamente y debería dar un resultado diferente para diferentes contraseñas.
fuente
Usar diferentes algoritmos de hashing es una mala idea: reducirá la entropía en lugar de aumentarla.
Sin embargo, suponiendo que tenga un algoritmo de hash criptográficamente fuerte y una buena solución, aplicar la misma función de hash varias veces hace que el proceso de hash sea computacionalmente más costoso. El beneficio de esto es que cuando fallan otros medios para descifrar el hash de contraseña (adivinanzas, ataques de diccionario, tablas de arco iris, etc.), y el atacante se ve obligado a utilizar técnicas de fuerza bruta, les toma más tiempo probar cada contraseña, simplemente porque tienen que aplicar la misma función hash con más frecuencia. Entonces, si una ronda de hashing requeriría un mes de fuerza bruta, aplicarlo doce veces aumentaría el tiempo estimado a un año.
Algoritmos hash recientes como bcrypt se basan en esta idea; contienen un parámetro para controlar la complejidad computacional del hash, para que pueda escalarlo a medida que avanza la velocidad del hardware: cuando el hardware se vuelve más rápido en un factor de dos, aumenta la complejidad para compensar, por lo que el tiempo requerido para forzar su los hash permanecen aproximadamente constantes.
fuente
No intente escribir su propio esquema de hash de contraseña a menos que esté dispuesto a tomar un curso en criptografía y / o ingeniería de seguridad.
Debe usar una implementación bien establecida de hashing de contraseña que a su vez debe usar una función de derivación de clave ( KDF ) como PBKDF2, bcrypt, scrypt o el Argon2 más nuevo.
Los buenos KDF incluyen un factor de trabajo, generalmente varias iteraciones, para aumentar el costo de los ataques fuera de línea. Se podría decir que estos KDF cambian la contraseña varias veces, utilizando el mismo algoritmo cada vez. No tiene sentido usar el algoritmo de resumen de mensajes múltiples, como lo señalan otros.
fuente
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:
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).
fuente
Tengo entendido que usar múltiples algoritmos de hashing es derrotar a las tablas de arcoiris . Usar una buena sal también funciona, pero supongo que es un segundo nivel de protección.
fuente
Esto no es más seguro. Sin embargo, tiene un protocolo de identificación basado en hash varias veces con la misma función.
Esto va de esa manera. El valor almacenado es hash ^ n (pass) en la computadora A. A pide a B que se autentique y le da a B el número entero n. B hace el cálculo hash ^ (n-1) (pasar) y lo envía de vuelta a A.
Una comprobación de hash (hash ^ (n-1) (pass)) == hash ^ n (pass). Si es cierto, entonces se realiza la autenticación. Pero entonces, A store hash ^ (n-1) (pass) y la próxima autenticación, dará B n-1 en lugar de n.
Esto garantiza que la contraseña nunca se intercambie de forma clara, que A nunca sepa cuál es la contraseña y que la autenticación esté protegida por la reproducción. Sin embargo, esto tiene el inconveniente de requerir una contraseña con una vida útil limitada. Cuando n alcanza el valor 2, se debe elegir una nueva contraseña después de la autenticación.
Otro uso de hash múltiple es la herramienta HMAC, para garantizar la autenticación e integridad de una solicitud. Para obtener más información sobre HMAC, consulte http://en.wikipedia.org/wiki/HMAC .
La mayoría del uso de hash múltiple en el mundo real son excesivos. En su caso, parece ser. Tenga en cuenta que si utiliza varias funciones hash, no todas tendrán la misma entropía, por lo que esto reduce la fuerza del hash. Por ejemplo, md5 tiene menos entropía que sha1, por lo que usar sha1 en un md5 no mejorará la fuerza del hash. La fuerza generalmente será igual a la fuerza de la función hash más débil.
fuente