Hachez le mot de passe en C#? Bcrypt / PBKDF2

j'ai cherché msdn et d'autres ressources sur la façon de faire cela, mais je n'ai pas trouvé de solutions claires. C'est le meilleur que j'ai trouvé http://blogs.msdn.com/b/shawnfa/archive/2004/04/14/generating-a-key-from-a-password.aspx?Redirected=true

j'aimerais hachez les mots de passe en C# en utilisant bcrypt ou PBKDF2 (qui semble être lié à bcrypt). J'aime expérimenter avec combien de tours il faut à mon ordinateur pour Hasher un mot de passe. Cependant tout semble être à propos de cryptage tandis que tout le monde parle de hachage. Je ne peux pas le comprendre. Comment hacher un mot de passe? Il ressemble plus à PBKDF2 (Rfc2898?) est un générateur de nombres aléatoires et j'utilise GetBytes (quantité) pour choisir la taille de mon hash.

je suis confus. Comment est-ce que je hacherais un mot de passe avec bcrypt/PBKDF?

33
demandé sur TrueWill 2012-07-10 16:01:24

7 réponses

PBKDF2

vous étiez vraiment proche en fait. Le lien que vous avez donné vous montre comment vous pouvez appeler la fonction Rfc2898DeriveBytes pour obtenir des résultats de hachage PBKDF2. Cependant, vous avez été éjecté par le fait que l'exemple utilisait la clé dérivée à des fins de cryptage (la motivation originale pour PBKDF1 et 2 était de créer des fonctions de dérivation "clé" adaptées à l'utilisation comme clés de cryptage). Bien sûr, nous ne voulons pas utiliser la sortie pour cryptage mais comme un hachage sur son propre.

vous pouvez essayer le SimpleCrypto.Net bibliothèque écrite pour exactement ce but si vous voulez PBKDF2. Si vous regardez la mise en œuvre , vous pouvez voir qu'il est en fait juste un emballage mince autour (vous l'avez deviné) Rfc2898DeriveBytes .

BCrypt

Vous pouvez essayer le C# de la mise en œuvre nommé (quoi d'autre) BCrypt.NET si vous voulez expérimenter cette variante.

clause de non-responsabilité: Je n'ai utilisé ni testé aucune des bibliothèques auxquelles j'ai fait référence... YMMV

31
répondu paracycle 2017-08-09 21:30:38

Il m'a fallu pour toujours (jours il a fallu des jours) à trouver quoi en fait le code pour obtenir les mots de passe hachés au travail!! donc je l'ai mis ici pour plus de commodité.

vous devez lire la documentation et theory1 theory2 et puis certains ou vous pourriez être ouvert à des failles de sécurité. La sécurité est un sujet très important! Acheteur Méfiez-Vous!

Ajouter le paquet NuGet BCrypt.Net à la solution

const int WorkFactor = 14;
var HashedPassword = BCrypt.Net.BCrypt.HashPassword(Password, WorkFactor); 

vous devez ajuster le WorkFactor à ce qui est approprié voir discussions . De son une log2 fonction

" le nombre est log2, donc chaque fois que les ordinateurs doublent la vitesse, ajouter 1 au nombre par défaut."

puis vous stockez le mot de passe hashé dans votre db en tant que passwordFromLocalDB et pour tester un password comme ceci:

if (BCrypt.Net.BCrypt.Verify(password, passwordFromLocalDB) == true)

Bonne Chance!

7
répondu JPK 2017-05-23 12:10:36

plus tôt cette année, je cherchais la même chose pour créer des hachures pour notre ASP.NET projet de formulaires Web, Je voulais le faire de la même façon que les projets MVC le font hors des sentiers battus.

je suis tombé sur cette question = > ASP.NET identité par défaut mot de passe Hasher, comment cela fonctionne - t-il et est-il sécurisé? Puis j'ai trouvé la source avec la méthode ByteArraysEqual ici = > http://www.symbolsource.org/MyGet/Metadata/aspnetwebstacknightly/Project/Microsoft.AspNet.Identity.Core/2.0.0-rtm-140327/Release/Default/Microsoft.AspNet.Identity.Core/Microsoft.AspNet.Identity.Core/Crypto.cs?ImageName=Microsoft.AspNet.Identity.Core

2
répondu Luke T O'Brien 2017-05-23 12:26:17

pour PBKDF2, vous pourriez être en mesure d'utiliser le système.Sécurité.Cryptographie.Rfc2898DeriveBytes.

voir MSDN ici: http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx

1
répondu Jay S 2012-07-10 12:23:23

PBKDF2 utilise HMACSHA1, si vous souhaitez une solution plus moderne et personnalisable, vous devriez regarder cette API en utilisant HMACSHA256 ou 512 avec étirement des clés tout comme PBKDF2

https://sourceforge.net/projects/pwdtknet /

exemple GUI inclus dans le code source a démontré comment obtenir un hachage à partir d'un mot de passe, y compris la création de sel de crypto aléatoire.....enjoy:)

1
répondu thashiznets 2012-10-04 03:45:12

PBKDF2

dans l'exemple de http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx , quand vous arrivez à la ligne " Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes (pwd1, salt1, myIterations);", k1 est la valeur de hachage. La raison pour laquelle l'exemple est pour le cryptage est que Rfc2898DeriveBytes a été initialement conçu pour créer des clés de cryptage.

Si vous ne fournissez pas de sel, Rfc2898DeriveBytes va créer son propre, mais je ne sais pas si RNGCryptoServiceProvider fait un meilleur travail d'être cryptographiquement aléatoire.

selon OWASP ( https://www.owasp.org/index.php/Using_Rfc2898DeriveBytes_for_PBKDF2 ), L'utilisation sous-jacente de SHA1 par Rfc2898DeriveBytes signifie qu'il est seulement bon pour les hachures jusqu'à 160 bits de longueur. Si vous créez un hachage plus long, un attaquant n'a toujours à se soucier que des 160 premiers bits, mais vous ont rendu le hachage de mot de passe/authentification Plus cher pour vous-même sans gain.

voici un exemple de code pour le hachage de mot de passe Rfc2898DeriveBytes (stocker le hachage, le sel et les itérations dans le DB):

public class Rfc2898PasswordEncoder
{
    private int _byteLength = 160 / 8; // 160 bit hash length

    public class EncodedPassword
    {
        public byte[] Hash { get; set; }
        public byte[] Salt { get; set; }
        public int Iterations { get; set; }
    }

    public EncodedPassword EncodePassword(string password, int iterations)
    {
        var populatedPassword = new EncodedPassword
        {
            Salt = CreateSalt(),
            Iterations = iterations
        };

        // Add Hash
        populatedPassword.Hash = CreateHash(password, populatedPassword.Salt, iterations);

        return populatedPassword;
    }

    public bool ValidatePassword(string password, EncodedPassword encodedPassword)
    {
        // Create Hash
        var testHash = CreateHash(password, encodedPassword.Salt, encodedPassword.Iterations);

        return testHash == encodedPassword.Hash;
    }

    public byte[] CreateSalt()
    {
        var salt = new byte[_byteLength]; // Salt should be same length as hash

        using (var saltGenerator = new RNGCryptoServiceProvider())
        {
            saltGenerator.GetBytes(salt);
        }

        return salt;
    }

    private byte[] CreateHash(string password, byte[] salt, long iterations)
    {
        byte[] hash;
        using (var hashGenerator = new Rfc2898DeriveBytes(password, salt, (int)iterations))
        {
            hash = hashGenerator.GetBytes(_byteLength);
        }

        return hash;
    }
} 
0
répondu Phil 2017-01-27 10:13:55

j'étais intéressé par des réponses qui n'impliquaient aucune bibliothèque.

j'ai lu cet article https://crackstation.net/hashing-security.htm qui relie une implémentation dans différentes langues C# parmi elles que je vais lier ici aussi

https://github.com/defuse/password-hashing/blob/master/PasswordStorage.cs

il est intéressant de noter qu'il utilise Rfc2898DeriveBytes comme mentionné à quelques reprises ici.

private static byte[] PBKDF2(string password, byte[] salt, int iterations, int outputBytes){
    using (var pbkdf2 = new Rfc2898DeriveBytes(password, salt)) {
        pbkdf2.IterationCount = iterations;
        return pbkdf2.GetBytes(outputBytes);
    }
}
0
répondu CyberFox 2018-01-23 03:14:46