Lo que estás haciendo aquí es, de hecho, definir una función hash: dada una función de cifrado Cifrar (K, M) donde K es la clave y M es el texto plano para cifrar, tú defines Hash (P) = Encrypt (P, PAG). Así que estás inventando una nueva función criptográfica.
Primero, para el hashing de contraseñas, no necesitas ninguna función hash antigua, ya que debe ser resistente al intento de craqueo de fuerza bruta, donde el atacante adivina cuál podría ser la contraseña, calcula Hash (adivina) y compara el resultado con el hash almacenado. Cualquiera que sea el algoritmo de hash que hagas, debes reforzarlo para incluir sal (para que los atacantes tengan que descifrar cada hash individualmente en lugar de ir a todas las cuentas a la vez y hacer que caigan las contraseñas más débiles) y hacer que la función del hash sea lenta (porque eso duele). el atacante, que necesita hacer muchas suposiciones erróneas, más que el defensor, que en su mayoría verificará los intentos correctos). Consulte ¿Cómo hash seguro de contraseñas? para obtener una explicación más detallada.
Puede crear una función hash lenta, salada a partir de una función hash normal, con una construcción como SSH (P, S) = Hash (Hash (... Hash (P + S)…)) (donde P + S es concatenación ). Esta no es necesariamente la mejor manera de hacerlo; por ejemplo, una buena función de hash de contraseñas para usos típicos debería requerir mucha memoria, ya que los servidores tienen mucha más memoria que el hardware especializado para descifrar contraseñas. Pero es un buen comienzo.
El problema sigue siendo si Hash (P) = Encrypt (P, P) es una buena función de hash. Esto no es automático; tenga en cuenta que algunos análisis de la seguridad de los algoritmos criptográficos se basan en que la clave y el texto en claro sean independientes.
Una de las principales dificultades es que el tamaño de la clave en la mayoría de los algoritmos de cifrado está muy limitado, a menudo constante. Por ejemplo, el algoritmo de cifrado estándar AES solo acepta tres tamaños de clave (8, 12 o 16 bytes). Si la contraseña (más sal) es demasiado corta, puede rellenarla con un carácter no válido, pero ¿qué puede hacer si es demasiado larga? La forma habitual de usar una clave basada en un material que es más largo que el tamaño de la clave es ... para aplicar una función hash (que acepta una longitud de entrada arbitraria) al material.
Si desea derivar una función hash a partir de un algoritmo de cifrado, en realidad hay una forma más simple: en lugar de Hash (P) = Encrypt (P, P), defina Hash (P) = Encrypt (P, 0), es decir cifre un bloque de texto sin formato de todos los ceros (o algún otro bloque de texto sin formato conocido). Eso es lo que hizo la función de hashing de contraseña original de Unix . La ventaja de este enfoque sobre Cifrado (P, P) es que puede beneficiarse de los análisis existentes del algoritmo: los algoritmos de cifrado están diseñados para resistir ataques de texto simple conocido. La limitación con la contraseña y el tamaño de sal permanece.