216 votes

Identifiant ASP.NET Password Password Hasher, comment cela fonctionne-t-il et est-il sécurisé?

Je me demande si le Mot de passe Hasher que la valeur par défaut est mis en œuvre dans le UserManager qui vient avec MVC 5 et ASP.NET l'Identité de Cadre, est suffisamment sécurisé? Et si oui, si vous pouviez m'expliquer comment cela fonctionne?

IPasswordHasher interface ressemble à ceci:

public interface IPasswordHasher
{
    string HashPassword(string password);
    PasswordVerificationResult VerifyHashedPassword(string hashedPassword, 
                                                       string providedPassword);
}

Comme vous pouvez le voir, il ne prend pas de sel, mais il est mentionné dans ce fil: "Asp.net l'Identité de hachage de mot de passe" qu'il ne enfait sel derrière les coulisses. Donc, je me demande comment fait-il cela? Et d'où vient ce sel provient?

Mon souci est que le sel est statique, ce qui le rend tout à fait précaire.

287voto

zespri Points 6865

Voici comment le défaut de mise en œuvre de travaux. Il utilise une Fonction de Dérivation de Clé aléatoire de sel pour produire de la valeur de hachage. Le sel est inclus dans le cadre de la sortie de la KDF. Ainsi, chaque fois que vous "hash" le même mot de passe que vous obtiendrez différentes tables de hachage. Pour vérifier le hachage de la sortie est divisée en arrière pour le sel et le reste, et le KDF est exécuté à nouveau sur le mot de passe spécifié avec le sel. Si le résultat correspond au reste de la sortie initiale de la valeur de hachage est vérifiée.

Hachage:

public static string HashPassword(string password)
{
    byte[] salt;
    byte[] buffer2;
    if (password == null)
    {
        throw new ArgumentNullException("password");
    }
    using (Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(password, 0x10, 0x3e8))
    {
        salt = bytes.Salt;
        buffer2 = bytes.GetBytes(0x20);
    }
    byte[] dst = new byte[0x31];
    Buffer.BlockCopy(salt, 0, dst, 1, 0x10);
    Buffer.BlockCopy(buffer2, 0, dst, 0x11, 0x20);
    return Convert.ToBase64String(dst);
}

Vérifier:

public static bool VerifyHashedPassword(string hashedPassword, string password)
{
    byte[] buffer4;
    if (hashedPassword == null)
    {
        return false;
    }
    if (password == null)
    {
        throw new ArgumentNullException("password");
    }
    byte[] src = Convert.FromBase64String(hashedPassword);
    if ((src.Length != 0x31) || (src[0] != 0))
    {
        return false;
    }
    byte[] dst = new byte[0x10];
    Buffer.BlockCopy(src, 1, dst, 0, 0x10);
    byte[] buffer3 = new byte[0x20];
    Buffer.BlockCopy(src, 0x11, buffer3, 0, 0x20);
    using (Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(password, dst, 0x3e8))
    {
        buffer4 = bytes.GetBytes(0x20);
    }
    return ByteArraysEqual(buffer3, buffer4);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X