Encontré una discusión en la que aprendí que lo que había estado haciendo no era, de hecho, salar las contraseñas, sino sazonarlas, y desde entonces he comenzado a hacer ambas cosas con una función como:
hash_function($salt.hash_function($pepper.$password)) [multiple iterations]
Ignorando el algoritmo hash elegido (quiero que esto sea una discusión sobre sales y pimientos y no algoritmos específicos, pero estoy usando uno seguro), ¿es esta una opción segura o debería hacer algo diferente? Para aquellos que no están familiarizados con los términos:
Una sal es un valor generado aleatoriamente que generalmente se almacena con la cadena en la base de datos diseñada para que sea imposible usar tablas hash para descifrar contraseñas. Como cada contraseña tiene su propia sal, todas deben ser forzadas individualmente para poder descifrarlas; sin embargo, como la sal se almacena en la base de datos con el hash de contraseña, un compromiso de la base de datos significa perder ambos.
Un pimiento es un valor estático de todo el sitio almacenado por separado de la base de datos (generalmente codificado en el código fuente de la aplicación) que pretende ser secreto. Se utiliza para que un compromiso de la base de datos no haga que la tabla de contraseñas de toda la aplicación sea bruta.
¿Me falta algo? ¿Salar y salpimentar mis contraseñas es la mejor opción para proteger la seguridad de mi usuario? ¿Hay alguna falla de seguridad potencial para hacerlo de esta manera?
Nota: Suponga a los fines de la discusión que la aplicación y la base de datos se almacenan en máquinas separadas, no comparten contraseñas, etc., por lo que una violación del servidor de la base de datos no significa automáticamente una violación del servidor de la aplicación.
Respuestas:
Okay. Ya que necesito escribir sobre esto una y otra vez , haré una última respuesta canónica solo con pimienta.
El aparente revés de los pimientos
Parece bastante obvio que los pimientos deberían hacer que las funciones hash sean más seguras. Quiero decir, si el atacante solo obtiene tu base de datos, las contraseñas de tus usuarios deberían ser seguras, ¿verdad? Parece lógico, ¿verdad?
Es por eso que tanta gente cree que los pimientos son una buena idea. Que tiene sentido".
La realidad de los pimientos
En los reinos de seguridad y criptografía, "tener sentido" no es suficiente. Algo tiene que ser demostrable y tener sentido para que se considere seguro. Además, tiene que ser implementable de manera sostenible. El sistema más seguro que no se puede mantener se considera inseguro (porque si alguna parte de esa seguridad se rompe, todo el sistema se desmorona).
Y los pimientos no se ajustan ni a los modelos comprobables ni a los que se pueden mantener ...
Problemas teóricos con pimientos
Ahora que hemos preparado el escenario, veamos qué hay de malo con los pimientos.
Alimentar un hash en otro puede ser peligroso.
En tu ejemplo, lo haces
hash_function($salt . hash_function($pepper . $password))
.Sabemos por experiencia pasada que "simplemente alimentar" un resultado de hash en otra función de hash puede disminuir la seguridad general. La razón es que ambas funciones hash pueden convertirse en un objetivo de ataque.
Es por eso que algoritmos como PBKDF2 utilizan operaciones especiales para combinarlos (hmac en ese caso).
El punto es que si bien no es un gran problema, tampoco es algo trivial simplemente tirar. Los sistemas de cifrado están diseñados para evitar casos de "debería funcionar", y en su lugar se centran en casos de "diseñados para funcionar".
Si bien esto puede parecer puramente teórico, de hecho no lo es. Por ejemplo, Bcrypt no puede aceptar contraseñas arbitrarias . Por lo tanto, pasar
bcrypt(hash(pw), salt)
puede resultar en un hash mucho más débil quebcrypt(pw, salt)
sihash()
devuelve una cadena binaria.Trabajando contra el diseño
La forma en que se diseñó bcrypt (y otros algoritmos de hashing de contraseñas) es trabajar con sal. El concepto de pimiento nunca fue introducido. Esto puede parecer una trivialidad, pero no lo es. La razón es que una sal no es un secreto. Es solo un valor que un atacante puede conocer. Un pimiento por otro lado, por definición es un secreto criptográfico.
Los algoritmos de hashing de contraseña actuales (bcrypt, pbkdf2, etc.) están diseñados para tomar solo un valor secreto (la contraseña). Agregar otro secreto al algoritmo no se ha estudiado en absoluto.
Eso no significa que no sea seguro. Significa que no sabemos si es seguro. Y la recomendación general con seguridad y criptografía es que si no lo sabemos, no lo es.
Entonces, hasta que los criptógrafos diseñen y examinen los algoritmos para usarlos con valores secretos (pimientos), los algoritmos actuales no deben usarse con ellos.
La complejidad es el enemigo de la seguridad
Lo creas o no, la complejidad es el enemigo de la seguridad . Hacer un algoritmo que parezca complejo puede ser seguro o no. Pero las posibilidades son bastante significativas de que no sea seguro.
Problemas significativos con pimientos
No es mantenible
Su implementación de pimientos impide la capacidad de girar la llave de pimiento. Como el pimiento se usa en la entrada de la función unidireccional, nunca se puede cambiar el pimiento durante la vida útil del valor. Esto significa que necesitarías crear algunos trucos inestables para que sea compatible con la rotación de teclas.
Esto es extremadamente importante ya que se requiere siempre que almacene secretos criptográficos. No tener un mecanismo para rotar las llaves (periódicamente y después de una violación) es una gran vulnerabilidad de seguridad.
Y su enfoque actual de Pepper requeriría que cada usuario tenga su contraseña completamente invalidada por una rotación, o espere hasta su próximo inicio de sesión para rotar (que puede que nunca sea ...)
Lo que básicamente hace que su enfoque sea inmediato.
Requiere que ruedes tu propio cripto
Dado que ningún algoritmo actual admite el concepto de un pimiento, requiere componer algoritmos o inventar otros nuevos para admitir un pimiento. Y si no puedes ver de inmediato por qué es algo realmente malo:
NUNCA haga rodar su propia cripto ...
La mejor manera
Entonces, de todos los problemas detallados anteriormente, hay dos formas de manejar la situación.
Simplemente use los algoritmos tal como existen
Si usa bcrypt o scrypt correctamente (con un alto costo), todas las contraseñas de diccionario menos las más débiles deberían ser estadísticamente seguras. El récord actual de hash bcrypt al costo 5 es de 71k hashes por segundo. A ese ritmo, incluso una contraseña aleatoria de 6 caracteres tardaría años en descifrarse. Y teniendo en cuenta que mi costo mínimo recomendado es 10, eso reduce los hashes por segundo en un factor de 32. Por lo tanto, estaríamos hablando solo de 2200 hashes por segundo. A ese ritmo, incluso algunas frases de diccionario o modificaciones pueden ser seguras.
Además, deberíamos verificar esas clases débiles de contraseñas en la puerta y no permitir que entren. A medida que el descifrado de contraseñas se hace más avanzado, también deberían hacerlo los requisitos de calidad de las contraseñas. Sigue siendo un juego estadístico, pero con una técnica de almacenamiento adecuada y contraseñas seguras, todos deberían ser prácticamente muy seguros ...
Cifre el hash de salida antes del almacenamiento
Existe en el ámbito de la seguridad un algoritmo diseñado para manejar todo lo que hemos dicho anteriormente. Es un cifrado en bloque. Es bueno, porque es reversible, por lo que podemos rotar las teclas (¡yay! ¡Mantenibilidad!). Es bueno porque se está utilizando según lo diseñado. Es bueno porque no le da al usuario información.
Miremos esa línea nuevamente. Digamos que un atacante conoce su algoritmo (que es necesario para la seguridad, de lo contrario es seguridad a través de la oscuridad). Con un enfoque tradicional de pimienta, el atacante puede crear una contraseña de centinela, y dado que conoce la sal y la salida, puede forzar la pimienta con fuerza bruta. Ok, es una posibilidad remota, pero es posible. Con un cifrado, el atacante no obtiene nada. Y dado que la sal es aleatoria, una contraseña centinela ni siquiera lo ayudará. Entonces, lo mejor que les queda es atacar la forma encriptada. Lo que significa que primero tienen que atacar su hash cifrado para recuperar la clave de cifrado y luego atacar los hash. Pero hay mucha investigación sobre el ataque de las cifras, por lo que queremos confiar en eso.
TL / DR
No uses pimientos. Hay una serie de problemas con ellos, y hay dos formas mejores: no usar ningún secreto del lado del servidor (sí, está bien) y cifrar el hash de salida usando un cifrado de bloque antes del almacenamiento.
fuente
Primero, deberíamos hablar sobre la ventaja exacta de un pimiento :
Un escenario típico sería la inyección de SQL, las copias de seguridad desechadas, los servidores descartados ... Estas situaciones no son tan infrecuentes como parece y, a menudo, no están bajo su control (servidor de alojamiento). Si utiliza...
... las contraseñas seguras están bien protegidas. Es casi imposible forzar una contraseña segura en esas condiciones, incluso cuando se conoce la sal. El problema son las contraseñas débiles, que forman parte de un diccionario de fuerza bruta o son derivaciones de ellas. Un ataque de diccionario revelará esos muy rápido, porque prueba solo las contraseñas más comunes.
La segunda pregunta es cómo aplicar la pimienta .
Una forma a menudo recomendada de aplicar una pimienta es combinar la contraseña y la pimienta antes de pasarla a la función hash:
Sin embargo, hay otra forma aún mejor:
Esto no solo permite agregar un secreto del lado del servidor, sino que también permite intercambiar $ serverSideKey, en caso de que sea necesario. Este método implica un poco más de trabajo, pero si el código alguna vez existe (biblioteca) no hay razón para no usarlo.
fuente
AES_ENCRYPT($passwordHash, $serverSideKey)
llamada de MySQL también sería una forma apropiada de implementar esto?El objetivo de la sal y la pimienta es aumentar el costo de una búsqueda de contraseña precalculada, llamada tabla de arcoiris.
En general, tratar de encontrar una colisión para un solo hash es difícil (suponiendo que el hash sea seguro). Sin embargo, con hashes cortos, es posible usar la computadora para generar todos los hashes posibles en una búsqueda en un disco duro. Esto se llama una mesa arcoiris. Si crea una tabla de arcoíris, puede salir al mundo y encontrar rápidamente contraseñas plausibles para cualquier hash (sin sal y sin sal).
El objetivo de un pimiento es hacer que la tabla del arco iris sea necesaria para hackear su lista de contraseñas única. Perder así más tiempo en el atacante para construir la mesa del arco iris.
Sin embargo, el objetivo de la sal es hacer que la tabla de arco iris para cada usuario sea única para el usuario, aumentando aún más la complejidad del ataque.
Realmente, el objetivo de la seguridad informática es casi nunca hacerlo (matemáticamente) imposible, solo matemáticamente y físicamente poco práctico (por ejemplo, en sistemas seguros se necesitaría toda la entropía en el universo (y más) para calcular la contraseña de un solo usuario).
fuente
root
accedes a nuestro servidor de base de datos , todavía no tienes acceso a nuestro servidor de aplicaciones), eso oculta pimienta en el código fuente (en nuestro archivo de configuración) proporcionaría seguridad adicional.No puedo ver el almacenamiento de un valor codificado en su código fuente como relevante para la seguridad. Es seguridad a través de la oscuridad.
Si un hacker adquiere su base de datos, podrá comenzar a forzar de forma bruta sus contraseñas de usuario. El pirata informático no tardará mucho en identificar su pimiento si logra descifrar algunas contraseñas.
fuente