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?
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
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!
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
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
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:)
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;
}
}
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);
}
}