La solución que describe es, en realidad, hashing.
Considere la función de hash MD5 . Funciona comenzando con un valor fijo convencional (el "IV") de longitud de 128 bits. Luego, para cada bloque de 512 bits de datos de entrada, se calcula una función de compresión , que toma como entrada el estado actual de 128 bits y el bloque de mensajes de 512 bits, y emite los siguientes 128 bits. estado. Si observa cómo funciona la función de compresión MD5, verá que es similar a un cifrado de bloque (un esquema de Feistel generalizado con cuatro sub-palabras) donde el bloque de mensaje de 512 bits se utiliza como clave. Entonces MD5 realmente funciona como lo describe: encripte un valor fijo, con la contraseña como clave. Si el valor fijo es específico del usuario, entonces es un tipo de "sal" (y eso es bueno para el hashing de contraseñas).
Entonces su pregunta es: ¿no podemos construir una función hash a partir de un cifrado de bloque? Y la respuesta es: sí, pero requiere algo de cuidado. Un cifrado de bloque típico como el AES está diseñado para el cifrado y su seguridad se ha analizado en ese contexto. Cuando convierte un cifrado de bloque en una función hash como se describe anteriormente, confía en que el cifrado de bloque sea robusto en formas que no se han explorado a fondo; necesita que el cifrado sea resistente a ataques relacionados con clave , que no son un problema en lo que respecta al cifrado, pero pueden ser mortales para una función hash. Por ejemplo, se sabe que el AES es algo débil con respecto a las claves relacionadas, por lo que usarlo "tal como está" en una función hash no es necesariamente una buena idea.
Whirlpool y Skein son dos funciones hash que reutilizan un cifrado de bloque: en ambos casos, un cifrado de bloque especializado, optimizado para la resistencia en esa situación específica.
Independientemente de los detalles del diseño de la función hash, cualquier el sistema de almacenamiento de contraseñas tiene una gran debilidad evidente, ya que almacena la contraseña o, al menos, un token de verificación de contraseña (algo que puede ser usado para decidir si una contraseña dada es correcta o no). Las contraseñas provienen de los cerebros de los seres humanos; ellos no pueden ser fuertes. Es muy posible enumerar la mayoría de las contraseñas potenciales.
Es inevitable que un servidor que verifique las contraseñas contenga suficiente información para, por ejemplo, verificar las contraseñas. Por lo tanto, si un atacante puede obtener un volcado del disco del servidor, también obtiene ese poder y puede probar las contraseñas "en casa". Este es un ataque de diccionario sin conexión . La única defensa conocida (posiblemente, la única defensa posible ) es hacer que cada verificación de contraseña sea intrínsecamente lenta, preferiblemente de forma configurable. ESO es el punto de bcrypt : el hashing de la contraseña utiliza millones de operaciones elementales, sin ningún conocimiento atajo, para que el atacante tenga que pagar un alto precio por cada intento.
Una función hash hecha en casa, construida a partir de un cifrado de bloque, fallará en eso, a menos que lo defina para usar no el cifrado uno , sino el cifrado sucesivo un millón . Seguiría siendo casero (eso es muy malo en criptografía; no confíes en los diseños hechos en casa), pero al menos no sería tan débil con respecto a los ataques de diccionario.