Est-ce le moyen de saler et de stocker un mot de passe dans Db?

Il existe plusieurs méthodes (même ici dans SO) et toutes mentionnent que le meilleur moyen de conserver le mot de passe dans la firebase database est de sauvegarder, pas le mot de passe, ni le mot de passe hased, mais de stocker le hachage d’un mot de passe salé .

Ma question est simple, mettre du code dessus, est-ce la bonne façon?

ssortingng username = "myUsr"; ssortingng password = "myPwd"; DateTime createDate = DateTime.UtcNow; // Salt it ssortingng saltedPwd = Ssortingng.Concat(password, createDate.Ticks.ToSsortingng()); // Hash it HMACSHA1 hash = new HMACSHA1(Encoding.Unicode.GetBytes(Helper.EncryptKey)); ssortingng encodedPwd = Convert.ToBase64Ssortingng( hash.ComputeHash(Encoding.Unicode.GetBytes(saltedPwd))); // Create User in the database db.CreateUser(username, encodedPwd, createDate); 

Table d’utilisateurs de firebase database

 user_id | username | password | create_date | last_access | active 

et lors de la connexion, relancez le processus et vérifiez si le encodedPwd est identique au mot de passe salted, hased fourni.

Ma seule préoccupation est: est-ce la meilleure façon de saler un mot de passe? Est-il possible d’utiliser la date de création (car cela changera toujours, et j’ai lu qu’il est préférable d’utiliser toujours un salt différent chaque fois que nous encodons un mot de passe …

Ou le salt devrait-il être une variable complètement différente?

Votre implémentation est probablement suffisante, mais il serait préférable d’utiliser un sel avec plus d’entropie: la valeur de ticks que vous utilisez actuellement sera toujours dans une plage relativement petite.

Je suggérerais d’utiliser quelque chose comme PBKDF2 pour faire le travail pour vous, via Rfc2898DeriveBytes :

 ssortingng username = "myUsr"; ssortingng password = "myPwd"; using (var deriveBytes = new Rfc2898DeriveBytes(password, 20)) // 20-byte salt { byte[] salt = deriveBytes.Salt; byte[] key = deriveBytes.GetBytes(20); // 20-byte key ssortingng encodedSalt = Convert.ToBase64Ssortingng(salt); ssortingng encodedKey = Convert.ToBase64Ssortingng(key); // store encodedSalt and encodedKey in database // you could optionally skip the encoding and store the byte arrays directly db.CreateUser(username, encodedSalt, encodedKey); } 

Et pour authentifier …

 ssortingng username = "myUsr"; ssortingng password = "myPwd"; ssortingng encodedSalt, encodedKey; // load encodedSalt and encodedKey from database for the given username byte[] salt = Convert.FromBase64Ssortingng(encodedSalt); byte[] key = Convert.FromBase64Ssortingng(encodedKey); using (var deriveBytes = new Rfc2898DeriveBytes(password, salt)) { byte[] testKey = deriveBytes.GetBytes(20); // 20-byte key if (!testKey.SequenceEqual(key)) throw new InvalidOperationException("Password is invalid!"); } 

Je me demande pourquoi personne n’a encore mentionné BCrypt . Il existe une implémentation prête à utiliser pour C #. Voir http://derekslager.com/blog/posts/2007/10/bcrypt-dotnet-strong-password-hashing-for-dotnet-and-mono.ashx

Ne réinventez pas la roue s’il existe des solutions éprouvées à votre problème.

Votre méthode fonctionne parfaitement, mais supposons que quelqu’un ait votre firebase database, mais pas votre base de code. Ils pourraient essentiellement comprendre que vous avez simplement concaténé le mot de passe et créer la date, et ils pourraient également procéder au reverse engineering de tous les mots de passe.

Vous voudrez peut-être injecter une chaîne unique qui n’existe que dans votre base de code pour un peu de protection supplémentaire.

 ssortingng username = "myUsr"; ssortingng password = "myPwd"; DateTime createDate = DateTime.UtcNow; // Salt it ssortingng saltedPwd = Ssortingng.Concat(password, SomeOtherClass.StaticKey, createDate.Ticks.ToSsortingng()); public class SomeOtherClass { public static ssortingng StaticKey = "#$%#$%superuniqueblahal$#%@#$43580"; // should probably be const/readonly, but whatever } 

Pourquoi ne pas essayer la méthode ProtectedData.Protect ?

Cette méthode peut être utilisée pour chiffrer des données telles que des mots de passe , des clés ou des chaînes de connexion. Le paramètre optionalEntropy vous permet d’append des données pour augmenter la complexité du cryptage . spécifiez null pour aucune complexité supplémentaire. Si elles sont fournies, ces informations doivent également être utilisées lors du déchiffrement des données à l’aide de la méthode Unprotect.

Je pense que l’idée avec CreateDate est suffisamment puissante, mais lorsque quelqu’un vole votre firebase database et votre code, votre sel est révélé. La sécurité basée sur “personne ne peut prendre mon code” est une mauvaise sécurité.

Vous pouvez simplement doubler le mot de passe … Et utiliser du sel dès le premier hachage.

 ssortingng Flavor(ssortingng passwd) { ssortingng fhash = Str2SHA1(passwd); ssortingng salt = fhash[2] + fhash [10] + fhash[1]; // or whatever... ssortingng realhash = Str2SHA1(hash + salt); } ssortingng Str2Sha1(ssortingng str){ ... }