Как проверить соленый и хешированный пароль в c # - PullRequest
0 голосов
/ 03 сентября 2018

Я использовал приведенный ниже метод для подсчета и хэширования паролей

public string CreateSalt(int size)
{
    var rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
    var buff = new byte[size];
    rng.GetBytes(buff);
    return Convert.ToBase64String(buff);
}
public string GenerateSHA256Hash(String input, String salt)
{
    byte[] bytes = System.Text.Encoding.UTF8.GetBytes(input + salt);
    System.Security.Cryptography.SHA256Managed sha256hashstring =
        new System.Security.Cryptography.SHA256Managed();
    byte[] hash = sha256hashstring.ComputeHash(bytes);
    return Convert.ToBase64String(hash);
}
public void Submit1_click(object sender, EventArgs r)
{

    try
    {
        String salt = CreateSalt(10);
        String hashedpassword = GenerateSHA256Hash(password1.Text, salt);
        string MyConString = "SERVER=localhost;DATABASE=mydb;UID=root;PASSWORD=abc123;";
        MySqlConnection connection = new MySqlConnection(MyConString);
        string cmdText = "INSERT INTO authentication(agentlogin ,password ,question ,answer)VALUES ( @login, @pwd, @question, @answer)";
        MySqlCommand cmd = new MySqlCommand(cmdText, connection);
        cmd.Parameters.AddWithValue("@login", labeluname.Text);
        cmd.Parameters.AddWithValue("@pwd", hashedpassword);
        cmd.Parameters.AddWithValue("@question", ddlquestion.Text);
        cmd.Parameters.AddWithValue("@answer", txtanswer.Text);
        connection.Open();
        int result = cmd.ExecuteNonQuery();
        connection.Close();
        lblmsg.Text = "Registered succesfully";
        lblmsg.ForeColor = System.Drawing.Color.Green;
        Response.Redirect("index.aspx");
    }
    catch (Exception)
    {
        Console.Write("not entered");
        lblmsg.Text = "Registration failed!";
        lblmsg.ForeColor = System.Drawing.Color.Red;
        Response.Redirect("index.aspx");
    }
}

Итак, я получаю полностью зашифрованный пароль из вышеперечисленного, но теперь я не могу войти, используя пароли, которые были там введены. Как я могу восстановить пароль при входе в систему? Я подумал, что могу просто использовать тот же метод, который использовался для шифрования, чтобы восстановить его, но соление не возвращает те же значения. Ниже приведен код на странице проверки

    public string GenerateSHA256Hash(String input)
    {
        byte[] bytes = System.Text.Encoding.UTF8.GetBytes(input);
        System.Security.Cryptography.SHA256Managed sha256hashstring =
            new System.Security.Cryptography.SHA256Managed();
        byte[] hash = sha256hashstring.ComputeHash(bytes);
        return Convert.ToBase64String(hash);
    }

    public void Login_click(object sender, EventArgs r)
    {
        String hashedpassword = GenerateSHA256Hash(txtpassword.Text);
        string MyConString = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
        MySqlConnection con = new MySqlConnection(MyConString);
        MySqlCommand cmd = new MySqlCommand("select * from authentication where agentlogin=@username and password=@word", con);
        cmd.Parameters.AddWithValue("@username", txtusername.Text);
        cmd.Parameters.AddWithValue("@word", hashedpassword);
        MySqlDataAdapter sda = new MySqlDataAdapter(cmd);
        DataTable dt = new DataTable();
        sda.Fill(dt);
        con.Open();
        int i = cmd.ExecuteNonQuery();
        con.Close();
        if (dt.Rows.Count > 0)
        {
            Session["id"] = txtusername.Text;
            Response.Redirect("calendar.aspx");
            Session.RemoveAll();
        }
        else
        {
            lblmsg.Text = "Credential doesn't match!";
            lblmsg.ForeColor = System.Drawing.Color.Red;

        }

    }

Ответы [ 3 ]

0 голосов
/ 03 сентября 2018

Вы должны сохранить соль, прежде чем добавлять ее к паролю и хешировать.

Таким образом, когда кто-то пытается войти в систему, вы объединяете пароль с сохраненной солью, а затем можете хэшировать его и сравнивать с существующим хешем в базе.

Итак, ваша пользовательская таблица должна иметь как минимум эти 3 столбца: имя пользователя, хеш-пароль, соль

более подробное объяснение: Функция хеширования является детерминированной, но не обратимой, поэтому, когда пользователь впервые создает свой пароль:

  • вы генерируете соль
  • вы соединяете пароль и соль
  • Вы хэшируете полученную строку конкатенации пароля и соли
  • Вы экономите и хеш, и соль

так что у вас есть: hashedpassword = хеш-функция (пароль + соль)

При попытке авторизации:

  • вы получаете логин и пароль в качестве ввода
  • с помощью логина вы можете получить хеш и соль в базе
  • у вас уже есть функция хеширования
  • чтобы вы могли обработать хеш-функцию (password_entered_by_user + salt)
  • вы сравниваете результат с hashedpassword и регистрируете пользователя, если он совпадает

Наличие соли рядом с хешированным паролем не делает его менее безопасным: цель соли - предотвратить использование rainbowtable

Если кто-то проникнет в вашу базу данных, он, вероятно, будет стремиться получить адрес электронной почты + пароль ваших пользователей, поскольку большинство людей используют один и тот же пароль и адрес электронной почты в разных местах.

Теперь, поскольку хеш-функция необратима, злоумышленник может лишь попытаться угадать пароль и создать словарь с:

guessed_password => hash(guessed_password)

например:

pet345 => 23FD7890F0F3FA3AE468F37CB900402A1F1977CF926F3452CA519056E16985AB
lola78 => 876B42DC10A0822CC52B894DC7517C784A542B43FB033B4A93635ADA67946B2E
lola79 => A7DCAF5195463FA367CDEA6F23688C1280EC98F4AF2B08BC3469D2496537D48D
lola80 => 8D8E1CF212F5DDC3CA1D510900382DF945625A9AE1584CE0D539B2C4D73717CB

если в вашей базе данных есть хеш (guessed_password), он знает, что пароль для этого (этих) пользователей - guessed_password.

Он может создать словарь с миллиардами guessed_passwords, и, поскольку многие пользователи не используют действительно надежный пароль, очень вероятно, что он сможет найти в своем словаре большое количество хешей ваших пользователей. Поэтому, если он генерирует хеши для «lola80» и «lola79», и это пароли 2 ваших пользователей, он знает, что это знает.

Теперь, если вы добавите случайную соль для каждого введенного пароля, для каждой соли он должен создать полный словарь, так как он должен сделать:

guessed_password + salt = hash(guessed_password + salt)

Для пользователя A с солью '09 ç @ p $ 'он должен создать полный словарь, где каждое слово заканчивается на '09 ç @ p $'

Теперь, если он хочет угадать пароль пользователя B, связанный с солью 'Yuè45gh', он должен создать еще один словарь, в котором каждое слово оканчивается на 'Yuè45gh'

По сути, это замедляет процесс угадывания ваших пользовательских паролей по коэффициенту your_number_of_users.

0 голосов
/ 04 сентября 2018

Создайте столбец в вашей пользовательской таблице Username и Hash и Salt

Регистрация пользователя

1) Получите данные username или password от пользователя в вашей регистрационной форме.

2) Создайте Hash and Salt для ввода пароля с помощью метода ниже.

public class HashSalt
{
    public string Hash { get; set; }
    public string Salt { get; set; }
}

public static HashSalt GenerateSaltedHash(int size, string password)
{
    var saltBytes = new byte[size];
    var provider = new RNGCryptoServiceProvider();
    provider.GetNonZeroBytes(saltBytes);
    var salt = Convert.ToBase64String(saltBytes);

    var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, saltBytes, 10000);
    var hashPassword = Convert.ToBase64String(rfc2898DeriveBytes.GetBytes(256));

    HashSalt hashSalt = new HashSalt { Hash = hashPassword, Salt = salt };
    return hashSalt;
}

Класс Rfc2898DeriveBytes используется для генерации хэша с использованием спецификации RFC2898, в которой используется метод, известный как PBKDF2 (Функция получения ключа на основе пароля # 2), и в настоящее время рекомендуется IETF (Целевая группа по инженерным вопросам интернета) для новых приложений.

3) Затем сохранили эти Hash и Salt с записью пользователя в базе данных.

public void Submit1_click(object sender, EventArgs r)
{
    //Your code here

    HashSalt hashSalt = GenerateSaltedHash(64, password1.Text);

    //Your code here

    cmd.Parameters.AddWithValue("@hash", hashSalt.Hash);
    cmd.Parameters.AddWithValue("@salt", hashSalt.Salt);

    //You code here
}

Логин пользователя

1) Получите ввод username или password от пользователя в форме входа в систему.

2) В Login_click получить пользователя по имени пользователя из базы данных.

3) Передать сохраненные значения Hash и Salt в функцию ниже.

public static bool VerifyPassword(string enteredPassword, string storedHash, string storedSalt)
{
    var saltBytes = Convert.FromBase64String(storedSalt);
    var rfc2898DeriveBytes = new Rfc2898DeriveBytes(enteredPassword, saltBytes, 10000);
    return Convert.ToBase64String(rfc2898DeriveBytes.GetBytes(256)) == storedHash;
}

4) Затем войдите в систему, подтвердив свой пароль.

public void Login_click(object sender, EventArgs r)
{
    //You code here

    User user = GetUserByUsername(txtUsername.Text);

    bool isPasswordMatched = VerifyPassword(txtpassword.Text, user.Hash, user.Salt);

    if (isPasswordMatched)
    {
        //Login Successfull
    }
    else
    {
        //Login Failed
    }

    //Your code here
}

Ссылка: Эффективное хеширование пароля

0 голосов
/ 03 сентября 2018

Я подумал, что могу использовать тот же метод, который использовался для шифрования, чтобы его восстановить, но соление не возвращает те же значения.

Вы имеете в виду, что вы отправили соленый пароль в другой раз через механизм соления и ожидали, что не зашифрованный чистый пароль? Это не имеет никакого смысла.

Итак, вы засолили пароль и сохранили его где-то. То, что вы должны сделать сейчас, это когда пользователь вводит свой пароль, вы солите этот новый пароль и получаете соленый пароль. Тогда сравните этот новый со старым; если они совпадают, это был правильный пароль.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...