Un método que podría usarse sería generar "errores tipográficos aceptables" al ingresar la contraseña inicial y luego almacenar los hashes de todos estos. Hay algunos problemas con esto: aumenta el tiempo requerido para un cambio de contraseña y para la verificación de la contraseña, especialmente si está utilizando un método de hashing de contraseña lento, como suele recomendarse, y aumenta los requisitos de almacenamiento en una cantidad potencialmente variable. / p>
Suponga que la contraseña utilizada es "Contraseña1!", y que los "errores tipográficos aceptables" son el caso de letras individuales (o la presencia de los caracteres apropiados al presionar Mayús y un número), el intercambio de caracteres adyacentes y la falta de un instancia única de un carácter duplicado (estos no son los únicos errores tipográficos posibles, pero a partir de mis errores tipográficos, ¡son muy fáciles de hacer!).
Eso significa que todo lo siguiente sería aceptable:
Password1!
aPssword1!
Psasword1!
Password1! [transposing "s" and "s"]
Paswsord1!
Passowrd1!
Passwrod1!
Passwodr1!
Passwor1d!
Password!1
password1!
PAssword1!
PaSsword1!
PasSword1!
PassWord1!
PasswOrd1!
PasswoRd1!
PassworD1!
Password!!
Password11
Pasword1!
Dado cualquier algoritmo de contraseña razonable (o MD5), todos estos tendrán hashes no relacionados:
2b4ae288a819f2bcf8e290332c838148
c435f7c0de60f0f69bce9f9a671e748a
8aed93fca5d9b2416c51fee36b03bc6b
9fbad358027d70c0db81fc23ab483c3c
dbf220c136f6b1f27c30997090da4697
c36fc47e48c2a52e450cd06f60bbd3bf
Para verificar una contraseña en este caso, hash la entrada y verifica todos los valores posibles. Incluso puede agregar la entrada a un nivel de cuenta, y solo tiene que calcular un hash. Aunque hay un fallo.
Saber todos estos hashes en realidad no ayuda directamente al atacante, pero puede aplicar las mismas reglas que usaste a cualquier lista de contraseñas que tienen, y si cualquiera de los hashes coincide, obtendrán acceso a la cuenta. Se aplica si usas una cuenta específica de sal también. La compensación por la velocidad de inicio de sesión también les ayuda.
Afortunadamente, es bastante fácil defenderse contra eso, con una sal específica de hachís. Si usas la mayoría de las implementaciones de bcrypt, obtendrás esto gratis:
Password1!:$2a$04$GgLXwKnxLmnLV/UUtbYahuT9L8R.8/SoKAnRKZUyCuEEgfrX5ITLm
password1!:$2a$04$5Ol8psikd7h0Gt/ZWtQAve0PdA/LO4oub/0JMGC5AA/Rsup/3SBbG
Ahora tienen que probar todas las modificaciones contra cada hash almacenado. Dependiendo de cómo almacene sus contraseñas, podrían ser capaces de optimizar qué variaciones intentan contra cada hash, pero como no saben si la contraseña correcta es "Contraseña1!" o "pAssword1!", existe el riesgo de que se pierdan cosas si lo hacen. Sin embargo, cuando alguien quiere iniciar sesión, debe hacer lo mismo.
Esta es la compensación: si utiliza un método de hash que toma 100 ms para calcular y necesita calcular 1 valor, tomará 100 ms para verificar. Si necesita verificar 10 versiones, tomará 1s de tiempo de procesamiento. Si realiza las comprobaciones una por una, obtendrá un problema de tiempo: las respuestas rápidas significan que se encontró la contraseña original, las más lentas significan que tiene un error tipográfico. Si los hace en paralelo, ha aumentado los requisitos informáticos para su sistema.
Usando solo la lista anterior de "errores tipográficos aceptables", obtienes un número variable de contraseñas potenciales. Para "Password1!", Eso significa que está almacenando 21 hashes, uno de los cuales es un duplicado de la contraseña original. Si necesita una salida de tiempo constante al iniciar sesión en su sistema (esto es algo bueno), debe poder calcular todos estos hashes en un tiempo determinado o retrasar cada inicio de sesión hasta el tiempo que llevaría calcular todos los hashes para la contraseña más larga que soporta. Si no lo haces, has creado una contraseña de oracle.
Existen métodos de hashing que permiten que una entrada similar dé como resultado hashes similares, pero estos no tienden a tener propiedades deseables para las contraseñas de hashing. En general, están optimizados para encontrar partes similares de estructuras de datos grandes, por lo que son de alta velocidad, lo que significa que se pueden probar rápidamente un gran número de contraseñas potenciales. Ellos, por definición, no tienen un efecto de avalancha, lo que significa que un ataque potencial podría probar contraseñas comunes y luego elegir el hash "más cercano" a los encontrados para mutaciones adicionales. Si un hash de salida de una mutación está "más cerca" de los almacenados, la entrada también está más cerca. Con un hash criptográfico, incluso uno rápido, se espera que el cambio de un solo carácter en la entrada cambie la mayor parte de la salida. No hay un concepto de "más cercano" en términos de salida, por lo que un atacante no puede hacer nada mejor que los cambios aleatorios, con la esperanza de obtener una coincidencia.
Si evita el problema de hash por completo y recorre la ruta de HSM, podría ser posible tener un HSM que almacene las contraseñas de texto sin formato de manera irrecuperable y que pueda producir respuestas de "original", "error tipográfico" y "no" utilizando métodos de comparación clásicos. Esto podría ser aceptable si permitió que algunas acciones iniciaran sesión en los usuarios, pero luego requirió que se proporcionara la contraseña correcta para las operaciones de alto riesgo (por ejemplo, cambiar la contraseña), pero es probable que no sea rentable para la mayoría de los proveedores.
Es ciertamente posible, pero hay muchos problemas potenciales al hacerlo, y no está claro si los beneficios de UX justificarían el esfuerzo. Probablemente sería mucho más fácil fomentar el uso de aplicaciones de administrador de contraseñas, ya que evitarán el riesgo de errores tipográficos en muchos casos.