Как проверить пароль и имя пользователя для приложения windows в c#? - PullRequest
1 голос
/ 10 апреля 2020

У меня есть простой логин windows приложение. Я успешно создал SQL базу данных на локальном хосте, которая содержит информацию о пользователе, такую ​​как Имя пользователя, Пароль (хэшированный), Соль и электронная почта, и я также успешно создал форму регистрации пользователя, где новый пользователь может ввести свои данные, и эти данные будут быть добавленным в базу данных, все работает нормально.

Но я не могу проверить Имя пользователя и Пароль по сохраненным значениям в строке, содержащей данные пользователя в базе данных (localhost), чтобы предоставить доступ.

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

Класс HashSalt.cs

        // --- constructor to initialize num_of_iterations
        public HashSalt(int numOfIterations)
        {
            num_of_iterations = numOfIterations;
        }

        // --- Generate Salt ---
        public string  generateSalt()
        {
            var salt = new byte[32];

            var randomProvider = new RNGCryptoServiceProvider();
            randomProvider.GetBytes(salt);

            return Convert.ToBase64String(salt);        // returns salt as a string
        }

        // --- converts salt string into byte[]
        public byte[] saltToByte(string salt)
        {
            var byteSalt = Convert.FromBase64String(salt);
            return byteSalt;
        }

        // --- Generate hash of(pass+salt) ---
        public string generateHash(string password, byte[] salt)
        {

            var rfc2898 = new Rfc2898DeriveBytes(password, salt, num_of_iterations);

            var Password = rfc2898.GetBytes(32);    // gives 32 byte encoded password

            return Convert.ToBase64String(Password);    // returns hash
        }

        // --- Authenticate User ---
        public bool AuthenticateUser(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;
        }







    }
}

И это мое Login.cs для формы входа

private void btnSignin_Click(object sender, EventArgs e)
        {
            string enteredPass = txtLoginPassword.Text;

            DbHandler db = new DbHandler();
            MySqlDataAdapter adapter = new MySqlDataAdapter();
            DataTable table = new DataTable();
            MySqlCommand cmd = new MySqlCommand("SELECT password, salt FROM student WHERE indexno=@index;", db.getConnection());
            db.openConnection();    // open connection

                cmd.Parameters.Add("@index", MySqlDbType.VarChar).Value = txtLoginusername.Text;

                adapter.SelectCommand = cmd;
                adapter.Fill(table);

                if (table.Rows.Count > 0)
                {
                    string pass = table.Rows[0][0].ToString();
                    string salt = table.Rows[0][1].ToString();

                    string newPass = hashSalt.generateHash(enteredPass, hashSalt.saltToByte(salt));

                    if (hashSalt.authenticateUser(enteredPass, pass, salt))
                    {
                        // MessageBox.Show("correct ='" + pass + "'\nEntered pass ='" + hashSalt.authenticateUser(enteredPass, pass, salt) + "'");
                        // --- form Records obj
                        Records gotoRecords = new Records();
                        gotoRecords.Show(); // goto Records
                        this.Hide();

                }
                    else
                    {
                        string message = "User name & Password did not Match!?";
                        string title = "Attention!";
                        MessageBoxButtons buttons = MessageBoxButtons.OK;
                        DialogResult result = MessageBox.Show(message, title, buttons, MessageBoxIcon.Warning);
                    }

                }
                else
                {
                    string message = "User name NotFound!?";
                    string title = "Attention!";
                    MessageBoxButtons buttons = MessageBoxButtons.OK;
                    DialogResult result = MessageBox.Show(message, title, buttons, MessageBoxIcon.Warning);
                }
            //this.Close();
            db.openConnection();    // close connection

Структура базы данных enter image description here Буду очень признателен, если вы дадите мне несколько инструкций для как это сделать.

1 Ответ

1 голос
/ 01 мая 2020

Я думаю, что проблема связана с типом столбца соли в вашей таблице mysql. Здесь

string newPass = hashSalt.generateHash(enteredPass, hashSalt.saltToByte(salt));

вы передаете salt, получая из базы данных метод saltToByte() для преобразования в byte array, поэтому я думаю, что вы планируете хранить свою соль в виде строки, используя возвращаемое значение generateSalt() метод. И преобразование его в byte array с использованием метода generateHash(), когда вам нужно аутентифицировать пользователя.

Это грязная реализация. Рекомендуем хранить соль как byte array, поэтому вам не нужно использовать saltToByte().

Кроме того, ваши байтовые ключи различаются в generateSalt() ключе байта, установленном в

var salt = new byte[32];

32-байтовый ключ, а в AuthenticateUser() вы используете 256-байтовый ключ rfc2898DeriveBytes.GetBytes(256)

...