c# - online - password salt generator




Est-ce le moyen de saler et de stocker un mot de passe en DB? (4)

Je me demande pourquoi personne n'a encore mentionné BCrypt . Il existe une implémentation prête à l'emploi 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 pour votre problème.

Il existe plusieurs façons (même ici dans SO) et ils mentionnent tous que la meilleure façon de garder le mot de passe sur la base de données est d'enregistrer, pas le mot de passe, pas le mot de passe, mais le hash d'un mot de passe salé .

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

string username = "myUsr";
string password = "myPwd";
DateTime createDate = DateTime.UtcNow;

// Salt it
string saltedPwd = String.Concat(password, createDate.Ticks.ToString());

// Hash it
HMACSHA1 hash = new HMACSHA1(Encoding.Unicode.GetBytes(Helper.EncryptKey));
string encodedPwd = Convert.ToBase64String(
                        hash.ComputeHash(Encoding.Unicode.GetBytes(saltedPwd)));

// Create User in the database
db.CreateUser(username, encodedPwd, createDate);

Table utilisateur de base de données

user_id | username | password | create_date | last_access | active

et lors de la connexion, recommencez le processus et vérifiez si encodedPwd est le même que le mot de passe salé fourni.

Ma seule préoccupation est, est-ce la meilleure façon de sel un mot de passe? Est-il correct 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 devrait être le salt une variable complètement différente?


Je pense que l'idée avec CreateDate est suffisamment puissante, mais quand quelqu'un vole votre DB 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 le sel du premier hachage.

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

Votre implémentation est probablement assez bonne, mais il serait préférable d'utiliser un salt avec plus d'entropie: la valeur des ticks que vous utilisez actuellement sera toujours dans une plage relativement petite.

Je suggère d'utiliser quelque chose comme PBKDF2 pour faire le travail pour vous, via Rfc2898DeriveBytes :

string username = "myUsr";
string password = "myPwd";

using (var deriveBytes = new Rfc2898DeriveBytes(password, 20)) // 20-byte salt
{
    byte[] salt = deriveBytes.Salt;
    byte[] key = deriveBytes.GetBytes(20); // 20-byte key

    string encodedSalt = Convert.ToBase64String(salt);
    string encodedKey = Convert.ToBase64String(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 ...

string username = "myUsr";
string password = "myPwd";

string encodedSalt, encodedKey;
// load encodedSalt and encodedKey from database for the given username
byte[] salt = Convert.FromBase64String(encodedSalt);
byte[] key = Convert.FromBase64String(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!");
}

Votre méthode est très bien, mais disons que quelqu'un a eu votre base de données, 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 inverser l'ingénierie de tous les mots de passe.

Vous pouvez injecter une chaîne unique qui n'existe que dans votre base de code pour une protection supplémentaire.

string username = "myUsr";
string password = "myPwd";
DateTime createDate = DateTime.UtcNow;

// Salt it
string saltedPwd = String.Concat(password, SomeOtherClass.StaticKey, createDate.Ticks.ToString());

public class SomeOtherClass
{
    public static string StaticKey = "#$%#$%superuniqueblahal$#%@#$43580"; // should probably be const/readonly, but whatever
}




passwords