Cómo implementar un historial de contraseña seguro

23

Las contraseñas no deben almacenarse en texto sin formato por razones obvias de seguridad: debe almacenar los hash y también debe generar el hash con cuidado para evitar ataques de la tabla del arco iris.

Sin embargo, por lo general usted tiene la obligación de almacenar los últimos n contraseñas y para hacer cumplir una mínima complejidad y el cambio mínimo entre las diferentes contraseñas (para evitar que el usuario utilice una secuencia como Password_1, Password_2, ..., Contraseña_ n ). Esto sería trivial con las contraseñas de texto sin formato, pero ¿cómo puede hacerlo almacenando solo hashes?

En otras palabras: ¿cómo es posible implementar un mecanismo de historial de contraseña seguro?

Wizard79
fuente
2
Relacionado: security.stackexchange.com/questions/4704/… (y por cierto ese sitio podría ser una mejor ubicación para esta pregunta). En cuanto al 'cambio mínimo', no se me ocurre ninguna alternativa para generar todas las opciones que podrían calificarse como 'cambio mínimo' (¡lo cual podría ser MUCHO dependiendo de su definición!) Y comparar los hashes. ¿Cuál es la definición de 'cambio mínimo'?
Kevin Vermeer
77
Almacenar las últimas contraseñas n solo significa que el usuario elegirá una secuencia que va de 1 a n + 1 .
Joachim Sauer
11
Soy muy escéptico de que dicha política de contraseña mejore la seguridad; En mi humilde opinión, aumenta las posibilidades de que las personas recurran a mantener su contraseña en una nota adhesiva. El enlace de Kevin es una buena discusión. @KevinVermeer: ​​en realidad puede medir la cantidad de cambio como la distancia de Levenshtein ( en.wikipedia.org/wiki/Levenshtein_distance ), también conocida como "distancia de edición".
Nathan Long
55
Si su seguridad es tan estricta, entonces también podría generar una contraseña aleatoria para el usuario, obligarla a usarla y cambiarla en un intervalo regular. De esa manera, tienes control total sobre su contraseña.
Reactgular
2
@nathan: Almacenar contraseñas en una nota adhesiva es realmente seguro. No es posible atacar la contraseña a menos que tenga acceso físico a la nota adhesiva, eliminando aproximadamente el 99% de las amenazas. Ponga esa nota dentro de una billetera o cartera, y básicamente necesita asaltar a la persona para obtenerla, lo que significa que se identifica una violación de seguridad y se puede mitigar.
mattnz

Respuestas:

22

Almacene los hashes y verifique una contraseña ingresada contra esos hashes almacenados, de la misma manera que verifica una contraseña al iniciar sesión. Tendría que generar contraseñas 'alternativas' a partir de la que se proporciona en base a patrones numéricos para detectar sus cambios 'mínimos'.

Al iniciar sesión, ya verifica la contraseña ingresada contra un hash, no es necesario almacenar la contraseña en texto sin formato. El mismo truco funciona cuando se trata de cambiar una contraseña, simplemente verifique las contraseñas ingresadas y 'mínimas de cambio' contra los hashes históricos. Si la nueva contraseña es satisfactoria, mueva el hash de contraseña actual al conjunto histórico y reemplácelo con un nuevo hash para la nueva contraseña.

Martijn Pieters
fuente
Por lo tanto, si el usuario introduce Password6 debería detectar la parte numérica, y tratar por ejemplo Password4 , Password5 , Password7 , y así sucesivamente. ¿Es eso correcto?
Wizard79
44
@Lorenzo: Correcto. Generar alternativas puede ser tan complejo como lo desee, solo asegúrese de encontrar el equilibrio correcto entre complejidad y riesgo (no permita que sus usuarios esperen 5 minutos mientras verifica todas las posibilidades con la posibilidad de desaparecer de ser un riesgo).
Martijn Pieters
No estoy seguro de que sugerir a los usuarios que incriminen el número al final es una buena sugerencia, eso es un poco predecible. Y se vuelve exponencialmente más si le dices a los usuarios que lo hagan.
Wyatt Barnett
2
@WyattBarnett: Nadie le dice a los usuarios que lo hagan. El punto es detectar a los usuarios que lo hacen y evitar que se use la contraseña 'incrementada'.
Martijn Pieters
Ah, leí completamente algo mal aquí. Lo siento.
Wyatt Barnett
28

Cuando el usuario cambie su contraseña, solicite que ingresen su contraseña anterior. Ahora tiene acceso a dos contraseñas de texto sin formato, aunque no esté almacenando contraseñas de texto sin formato en su base de datos.

Realice las verificaciones que desee en estas dos contraseñas. Esto no evitará que el usuario alterne entre dos contraseñas (con un sufijo; puede evitar la alternancia directa según las sugerencias en otras respuestas), pero evitará los casos más evidentes.

Brian
fuente
Bueno, esta es sin duda una solución inteligente si no tiene el requisito de probar contra n contraseñas anteriores, sin embargo, la sugerencia de generar las alternativas justo a tiempo es mejor. ¡Pero generar alternativas de ambas contraseñas es aún mejor!
Wizard79
2
@Lorenzo: La idea es que hagas una prueba directa con las n contraseñas anteriores y una prueba más fuerte con la última contraseña. Es un compromiso.
Brian
Sí. Si su contraseña actual es potatoSalad1y desean actualizarla potatoSalad2, usted dice que el cambio es demasiado pequeño porque tiene ambas contraseñas de texto sin formato en ese momento. Pero más atrás de eso, solo tiene hashes, y la naturaleza de los hashes es que no puede decir si dos hashes tenían texto plano similar o completamente diferente como entrada.
Nathan Long
7

para agregar a la respuesta de @ martijnPieter, el cambio mínimo se puede implementar haciendo una fuerza bruta corta basada en las contraseñas nuevas y anteriores (que ambos tienen disponible)

por ejemplo, puede iterar sobre todas las contraseñas con una distancia de 1 o 2 de la nueva contraseña y ver si coincide con un pase anterior

pero es posible que desee tener en cuenta que esto puede reducir la confianza de los usuarios de que está utilizando contraseñas hash (ya que básicamente está diciendo que puede recuperar una contraseña anterior para rechazar una nueva contraseña)

monstruo de trinquete
fuente
Pero hay muchas secuencias con distancias de Hamming más grandes, como febrero de 2012 -> marzo de 2012 o viernes-09-28-12 -> martes-11-27-12 (fechas), contraseña_Alfa -> contraseña_Beta, pase_1111 -> Pass_2222, Pass_qwer, Pass_tyui, Pase, _op [] u Once -> Doce (sistemas de conteo alternativos), o FrankSmith -> FredJones -> FriarTuck o enojo -> animal -> manzana (nombres en un directorio de la compañía o palabras en un diccionario) que un atacante con la (s) contraseña (s) anterior (s) podría (n) adivinar fácilmente pero su algoritmo tendría dificultades para generar
Kevin Vermeer
@KevinVermeer luego toma en cuenta a los que están en tu generador de variaciones y acepta que nunca lo obtendrás todo
fanático del trinquete el
+1 para reducir la confianza. Cuando veo que algo me dice que mi contraseña es muy parecida a la que usé hace tres meses, al instante me pregunto si las están almacenando de forma reversible ... o si tienen un programador increíble. El escepticismo generalmente gana.
Tim Post
5

Esto es realmente más un apéndice a la inteligente respuesta de @ Brian. También felicito a @Martijn Pieters por agregar detalles sobre cómo forzar con fuerza bruta las contraseñas antiguas basadas en la actual y a @ratchet freak por "distancia de martilleo". No estoy eliminando mi respuesta porque creo que proporciona antecedentes interesantes para respaldarlos.

El almacenamiento de contraseñas de última generación requiere el uso de múltiples rondas de un hash criptográfico unidireccional fuerte (SHA-512 +) con sal única (128 bits +) para cada usuario. Pero no se sienta tentado a almacenar información adicional sobre cada contraseña. Cuanta más información almacene sobre cada contraseña, más socavará la seguridad de su algoritmo de hash.

Ejemplo

Considere lo fácil que resulta forzar una contraseña por fuerza bruta si sabe que:

  • Tiene 7 caracteres de largo
  • Los caracteres 3-5 son mayúsculas (4 es más bajo)
  • 1 y 7 son números
  • 6 es un símbolo

Un teclado de EE. UU. Tiene 95 caracteres imprimibles, por lo que saber que la contraseña tiene 7 caracteres de largo produce 95 ^ 7 = 69,833,729,610,000 = 7x10 ^ 13 permutaciones. Si fuera realmente aleatorio, podría llevar un año descifrar esto en un solo procesador de 3Ghz. Pero:

  • Solo hay 26 caracteres en mayúscula y 26 en minúscula
  • Solo hay 10 dígitos que producen 100 posibilidades para esos dos números
  • Solo hay 32 símbolos

Entonces (corregido gracias a @Hellion):

         26^4 (charcters 2-5 are known upper or lower-case)
        x 100 (characters 1 & 7 are digits)
        x  32 (character 6 is a symbol)
         ====
1,462,323,200 possible passwords.

¡Eso es 50,000 veces más fácil de descifrar! El almacenamiento de buena información para evitar contraseñas similares en este caso ha tomado su tiempo de crack para una contraseña de 7 caracteres de un año a un par de horas. Ahora es muy factible decodificar todas sus contraseñas en un potente escritorio multiprocesador con una buena tarjeta de video y un poco de paciencia. Espero que este simple ejemplo demuestre que cuanto más significativa sea la comparación de contraseñas similares, menos seguro será su hashing.

Importancia de Hashing fuerte

Las bases de datos con contraseñas se roban regularmente, con grandes robos en las noticias cada mes. Diablos, el mes pasado el estado de SC perdió los números de seguridad social de todos, ¡Uy! ¿Cuántas más de estas infracciones están cubiertas?

Pensamiento de cierre

Lo más aterrador para mí es cuando las personas eligen la misma contraseña o una similar para varios sitios, de modo que romper en uno le da acceso al atacante a todos ellos. Me encantaría ver un método probado para prevenir esa situación, aunque creo que evitar las contraseñas incorrectas más comunes ayudaría más que evitar que un usuario individual reutilice su contraseña incorrecta en el mismo sitio. Lo mejor que puedo sugerir es una política de toda la empresa para usar un administrador de contraseñas seguro que genere contraseñas altamente aleatorias para cada uno de sus usuarios y las almacene de forma segura.

GlenPeterson
fuente
1
nit menor: las posibilidades de contraseña siguen siendo multiplicativas, por lo que es (26 ^ 4) * 100 * 32 = 1,462,323,200. Si suponemos que las posibilidades de craqueo (95 ^ 7) toman un año, entonces el craqueo de este menor número de posibilidades tomará aproximadamente 11 minutos.
Hellion
@Hellion - ¡Vaya! Gracias por señalar eso. Lo he corregido.
GlenPeterson
1

Primero, puede almacenar los hashes de las últimas "n" contraseñas anteriores, para que pueda verificar si su nueva contraseña duplica una contraseña anterior. También tiene el texto sin formato de su contraseña actual (porque han iniciado sesión o se la han proporcionado para autenticar su solicitud de cambio de contraseña), y su nueva contraseña, para que pueda verificar los cambios mínimos entre estas dos contraseñas.

Si (para usted) es muy importante comparar directamente estas dos contraseñas con "n" contraseñas anteriores, entonces debe almacenar estas contraseñas (encriptadas) para poder recuperarlas más tarde.

Si bien podría verse como una falla de seguridad hacer esto, los métodos de encriptación podrían implementarse para proporcionar seguridad suficiente.

  1. Almacene cada contraseña (encriptada), para las últimas contraseñas "n".
  2. Almacene la fecha y hora en que se creó la contraseña más reciente.
  3. Almacene el hash de la contraseña más reciente.
  4. Cifre todas las contraseñas utilizando el hash (salado) de la contraseña actual y la marca de tiempo de creación de contraseña, y tal vez algo como un número de cuenta o dirección de correo electrónico.
  5. Desencripte y vuelva a encriptar todas las contraseñas cada vez que se cree una nueva contraseña.

Luego, cada vez que se cambia la contraseña, puede descodificar todas las contraseñas antiguas y hacer todas sus pruebas de cambio mínimo.

Ahora, si alguien tuviera la contraseña de esta persona y supiera todos los demás detalles necesarios, podría descodificar esta información para esta persona. Pero si ya tienen la contraseña de esta persona, ya pueden iniciar sesión como esta persona y acceder a la cuenta de esta persona.

Además, para las contraseñas antiguas, es posible que no tengan que almacenarse en texto estrictamente simple. Podrían almacenarse de alguna manera ofuscada. O almacenado como una lista alfabética de los caracteres en la contraseña.

No digo que esto sea algo recomendado en el caso general, pero suponiendo que la tarea que ha descrito es necesaria en su caso, esta es una forma de lograrlo con algunas medidas de seguridad.

Kevin Fegan
fuente
Esta respuesta hace varias sugerencias terribles en términos de seguridad. No deberíamos poder descifrar fácilmente las contraseñas, ni almacenarlas de "alguna manera ofuscada" en lugar de cifrarlas fuertemente.
user45623