Я снова и снова читал код, чтобы узнать, где происходит ошибка, но я не могу его найти. Я скопировал этот код из stackoverflow, который никогда не проверял его или не понимал, как это исправить. Я получаю пароли из веб-сервиса, хеширования, соления и сохранения его в SqlServer 2008. Переменные на SqlServer объявляются как почта как nvarchar (64), хэш как varbinary (128) и соль как varbinary (128) , Пароли сохраняются, но когда я пытаюсь проверить правильность пароля, метод всегда возвращает false. Это мои методы.Хеширование пароля для SqlServer
public int InsertData(string mail,string 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(string 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;
}
}
И следующий метод является один я использую для проверки де пароль, он всегда возвращает ложь
private bool CheckPassword(string 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;
}
}
Этот метод получает данные для входа
public bool ValidateLogIn(string mail, string Password)
{
using (SqlConnection connection = new SqlConnection(Connection))
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "Select * from Usuarios where [email protected]";
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;
}
}
}
}
Любые идеи, что может быть неправильно?
EDIT: Я нашел ссылку, где я получил код хэширования https://stackoverflow.com/a/4330586/1861617
Являются ли хэш и соль одинаковыми при сохранении и подтверждении данных? – Sam
Да, я сохраняю хэш и соль в одном ряду. Затем загрузите ту же строку и подтвердите ее с помощью пароля. –
Вы пытались установить точки останова в любом месте вашего кода и после выполнения на 100% убедиться, что переменные содержат то, что, по вашему мнению, они хранят (и для проверки кода ведет себя как ожидалось)? Кроме того, вы получаете какие-либо ошибки? – Sam