¿Cómo hash una contraseña en C #? [duplicar]

1

Supongo que la mejor manera de manejar las contraseñas para un sitio web es crear un hash de la contraseña y guardar ese hash en mi base de datos. Luego, cuando alguien intenta iniciar sesión, hago un hash de la contraseña que ingresaron y comparo.

¿Esto es correcto?

Y, ¿hay algún código de ejemplo que muestre cómo hacer esto en C #?

¿Y debo agregar un texto estándar a cada contraseña para que el texto que se está copiando tenga siempre al menos 20 caracteres?

Actualización: los otros enlaces no tienen código, así que esto es lo que implementé para esta pregunta. No incluyo el nombre de usuario porque eso puede cambiar, así que simplemente salt: contraseña. the: funciona porque uuencode no incluye un:.

public static class EncryptionUtilities
{
    private const int SALT_SIZE = 8;
    private const int NUM_ITERATIONS = 1000;

    private static readonly RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

    /// <summary>
    /// Creates a signature for a password.
    /// </summary>
    /// <param name="password">The password to hash.</param>
    /// <returns>the "salt:hash" for the password.</returns>
    public static string CreatePasswordSalt(string password)
    {
        byte[] buf = new byte[SALT_SIZE];
        rng.GetBytes(buf);
        string salt = Convert.ToBase64String(buf);

        Rfc2898DeriveBytes deriver2898 = new Rfc2898DeriveBytes(password.Trim(), buf, NUM_ITERATIONS);
        string hash = Convert.ToBase64String(deriver2898.GetBytes(16));
        return salt + ':' + hash;
    }

    /// <summary>
    /// Validate if a password will generate the passed in salt:hash.
    /// </summary>
    /// <param name="password">The password to validate.</param>
    /// <param name="saltHash">The "salt:hash" this password should generate.</param>
    /// <returns>true if we have a match.</returns>
    public static bool IsPasswordValid(string password, string saltHash)
    {
        string[] parts = saltHash.Split(new[] {':'}, StringSplitOptions.RemoveEmptyEntries);
        if (parts.Length != 2)
            return false;
        byte[] buf = Convert.FromBase64String(parts[0]);
        Rfc2898DeriveBytes deriver2898 = new Rfc2898DeriveBytes(password.Trim(), buf, NUM_ITERATIONS);
        string computedHash = Convert.ToBase64String(deriver2898.GetBytes(16));
        return parts[1].Equals(computedHash);
    }
}

ps: consideré agregar "The World Wonders" al texto hash porque es la sal más famosa de todos los tiempos. Sin embargo, pensé que no añadía nada y el cifrado no es el lugar para introducir cadenas históricas.

    
pregunta David Thielen 21.09.2014 - 22:18
fuente

1 respuesta

1

Sí, debe agregar un texto a cada contraseña para que el texto que se está copiando tenga siempre al menos una X, esto se denomina sal, y debe ser único para cada usuario.

Una entrada de la base de datos podría tener este aspecto:

nombre de usuario: contraseña: sal

bob: qiyh4XPJGsOZ2MEAyLkfWqeQ: zyIIMSYjiPm0L7a6

la sal se debe generar aleatoriamente cuando se crea la cuenta, y luego concatenar la sal con la entrada de la contraseña del usuario, ejecutarla a través de un algoritmo de hashing de una vía (varias veces para reducir la velocidad), y luego guardar el en el campo de contraseña, y duplique el procedimiento al iniciar sesión, luego compare las dos cadenas (asegúrese de hacer una comparación completa, no se detenga una vez que note que las cadenas ya no coinciden, para evitar un ataque de tiempo)

para una implementación real verificaría enlace de Ángel

    
respondido por el user2813274 21.09.2014 - 22:29
fuente

Lea otras preguntas en las etiquetas