Estoy usando Rfc2898DeriveBytes
para generar de forma segura la clave de cifrado y el vector de inicialización a partir de la contraseña de cadena suministrada por el usuario, para usar con encriptación simétrica (por ejemplo, AesManaged).¿Está bien usar el hash SHA1 de contraseña como un valor saliente al derivar la clave de cifrado y IV de la cadena de contraseña?
Estoy tomando el hash SHA1 de la contraseña como un parámetro salt a Rfc2898DeriveBytes
. ¿Eso esta bien? Si no, ¿de dónde debería obtener la sal? Necesitaré la misma sal cuando descifre, ¿verdad? Así que tengo que guardarlo en algún lugar sin cifrar, no seguro. Si tengo que almacenarlo de forma segura, se convierte en otra "contraseña", ¿no es así?
void SecureDeriveKeyAndIvFromPassword(string password, int iterations,
int keySize, int ivSize, out byte[] key, out byte[] iv)
{
// Generate the salt from password:
byte[] salt = (new SHA1Managed()).ComputeHash(Encoding.UTF8.GetBytes(password));
// Derive key and IV bytes from password:
Rfc2898DeriveBytes derivedBytes = new Rfc2898DeriveBytes(password, salt, iterations);
key = derivedBytes.GetBytes(keySize);
iv = derivedBytes.GetBytes(ivSize);
}
He visto usar la sal constante (codificada), y he visto personas quejándose de ella. Pensé que derivar la sal de la contraseña sería la mejor idea, pero no estoy seguro de que esta sea una solución óptima.
En breve, tengo un archivo que necesita ser encriptado, y una cadena de contraseñas ingresada por el usuario. ¿Cómo uso correctamente Rfc2898DeriveBytes
para derivar clave de encriptación segura y IV?
Gracias.
EDIT:
Gracias por sus respuestas. Ahora entiendo que el principal (¿tal vez solo?) Propósito de la sal es hacer imposible la generación de tablas de arcoiris; no se puede pregenerar el hash de "P @ $$ w0rd" porque tendrá un hash diferente para cada posible valor de sal. Entiendo esto perfectamente, PERO ... ¿Esto es realmente relevante para el cifrado simétrico? No estoy almacenando el hash en ninguna parte, ¿verdad? Entonces, incluso si el atacante tiene la tabla rainbow para todas las posibles combinaciones de contraseñas, no puede hacer mucho, ¿verdad?
Por lo tanto, mi pregunta ahora es: ¿hay alguna ventaja de utilizar la sal al azar en cada operación de cifrado, en comparación con el uso de la contraseña derivado (o modificable incluso) sal, cuando se utiliza con algoritmos de cifrado simétrico (como AesManaged of .NET)?
Es mejor almacenar solo el valor hash de una contraseña. A diferencia de una contraseña cifrada, el valor hash no puede revertirse, incluso si el atacante controla su código y conoce la clave. Entonces, ¿por qué cifrarías la contraseña (PBKDF2 no es encriptación, es hash)? – martinstoeckli
@martinstoeckli, no estoy encriptando la contraseña, ni estoy almacenando su hash en ningún lado. Acabo de derivar la clave de cifrado (y iv) de la contraseña de cadena y luego encriptar la carga útil con ella. –
Creo que ahora entiendo. Primero quiere calcular el hash de la contraseña y luego usar este valor hash para cifrar algunos datos (en lugar de usar la contraseña original directamente). – martinstoeckli