Hashing mot de passe pour SqlServer

J'ai lu encore et encore le code pour voir où l'erreur est faite mais je suis incapable de le find. J'ai copié ce code depuis stackoverflow et je ne l'ai jamais vraiment vérifié ou compris parfaitement pour le réparer. Je reçois des passwords d'un webservice, les hachant, les salant et les enregistrant dans un SqlServer 2008. Les variables sur le SqlServer sont déclarées comme mail comme nvarchar (64), hash comme varbinary (128) et salt comme varbinary (128). Les passwords sont en cours d'logging mais lorsque j'essaie de vérifier si le mot de passe est correct, la méthode renvoie toujours false. Ce sont mes methods.

public int InsertData(ssortingng mail,ssortingng Password) { int lineas; UserData usuario = HashPassword(Password); using (SqlConnection connection = new SqlConnection(Connection)) using (SqlCommand command = connection.CreateCommand()) { command.CommandText = "INSERT INTO Usuarios (Mail,Hash,Salt) VALUES (@mail,@hash,@salt)"; command.Parameters.AddWithValue("@mail", mail); command.Parameters.AddWithValue("@hash", usuario.Password); command.Parameters.AddWithValue("@salt", usuario.salt); connection.Open(); lineas=command.ExecuteNonQuery(); } usuario = null; return lineas; } private UserData HashPassword(ssortingng Password) { //This method hashes the user password and saves it into the object UserData using (var deriveBytes = new Rfc2898DeriveBytes(Password, 20)) { byte[] salt = deriveBytes.Salt; byte[] key = deriveBytes.GetBytes(20); // derive a 20-byte key UserData usuario = new UserData(); usuario.Password = key; usuario.salt = salt; return usuario; } } 

Et la méthode suivante est celle que j'utilise pour valider le mot de passe, elle renvoie toujours false

 private bool CheckPassword(ssortingng Password, byte[] hash, byte[] salt) { // load salt and key from database using (var deriveBytes = new Rfc2898DeriveBytes(Password, salt)) { byte[] newKey = deriveBytes.GetBytes(20); // derive a 20-byte key if (!newKey.SequenceEqual(hash)) return false; else return true; } } 

Cette méthode reçoit les informations de connection

  public bool ValidateLogIn(ssortingng mail, ssortingng Password) { using (SqlConnection connection = new SqlConnection(Connection)) using (SqlCommand command = connection.CreateCommand()) { command.CommandText = "Select * from Usuarios where Mail=@mail"; command.Parameters.AddWithValue("@mail",mail); connection.Open(); using (SqlDataReader reader = command.ExecuteReader()) { reader.Read(); byte[] hash = (byte[])reader["Hash"]; byte[] salt = (byte[])reader["Salt"]; if(CheckPassword(Password,hash,salt)) { / UpdateData(mail, Password); return true; } else { return false; } } } } 

Des idées sur ce qui pourrait être faux?

EDIT: J'ai trouvé le lien où j'ai obtenu le code de hachage https://stackoverflow.com/a/4330586/1861617

En utilisant votre code dans un projet de test (Windows Forms avec textbox + button + label), j'ai ajouté ceci:

  internal class UserData { public byte[] Password { get; set; } public byte[] Salt { get; set; } } public ssortingng Connection { get; set; } private void UpdateData(ssortingng mail, ssortingng password) { // not a clue what to do here.... } private void button1_Click(object sender, EventArgs e) { var password = textBox1.Text; var u = HashPassword(password); var b = new SqlConnectionSsortingngBuilder {DataSource = "127.0.0.1", IntegratedSecurity = true}; Connection = b.ConnectionSsortingng; InsertData("[email protected]", password); label1.Text = ssortingng.Format("Using direct check: {0}\nVia the database: {1}", CheckPassword(password, u.Password, u.Salt), ValidateLogIn("[email protected]", password)); } 

Et cela revient vrai, vrai sans aucun problème. (VS2010, .Net4 CP, SQL2008R2)

Sur la database j'ai utilisé ceci:

 CREATE TABLE tempdb..t_hash ( Mail nvarchar(64) NOT NULL PRIMARY KEY (Mail), Hash varbinary(128), Salt varbinary(128) ) 

Ma meilleure supposition est que votre définition pour le clas UserData est 'défectueuse'?

Après avoir vérifié avec la réponse de Deroby et toujours pas de chance. J'ai revérifié et réalisé 20 octets sont 120 bits de sorte que le varbinary n'était pas capable de stocker le sel entier. Après l'avoir augmenté à 256 ça a marché.