Некорректный вывод с использованием Rfc2898DeriveBytes для хеширования пароля - PullRequest
0 голосов
/ 15 ноября 2011

Я, конечно, уверен, что я делаю что-то не так здесь. Используя .net реализацию алгоритма, я хэшировал пароль для хранения в базе данных вместе с солью, используемой для хэширования. При проверке того же пароля с существующим хешем не совпадает. Вот мой код

Новая запись

byte[] SALT = GetRandomKey();
string password = Convert.ToBase64String((new Rfc2898DeriveBytes(txtPassword.Text, SALT)).GetBytes(20));
Session["test"] = password;
Session["salt"] = Convert.ToBase64String(SALT);

Пользователи

string HASHEDPASSWORD = Session["test"];
string SALT = Session["salt"];
string ouput = Convert.ToBase64String((new Rfc2898DeriveBytes(password, Encoding.Unicode.GetBytes(SALT))).GetBytes(20));
ltrResult.Text = HASHEDPASSWORD.Equals(ouput) ? "EQUAL" : "NOT EQUAL";

Получить метод RandomKey

byte[] GetRandomKey()
    {
        byte[] secretkey = new Byte[64];
        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
        rng.GetBytes(secretkey);
        return secretkey;
    }

Ответы [ 3 ]

3 голосов
/ 15 ноября 2011

или Convert.FromBase64String вместо Encoding.Unicode.GetBytes.

1 голос
/ 15 ноября 2011

Вы используете Convert.ToBase64String при добавлении элементов и Encoding.Unicode.GetBytes при его получении ...

Используйте Encoding.Unicode.GetString при добавлении новой записи, и ваш код должен работать, например:

private static string GetString(byte[] bytes)
{
    return Encoding.Unicode.GetString(bytes);
}

private static byte[] GetBytes(string value)
{
    return Encoding.Unicode.GetBytes(value);
}

Добавление

byte[] salt = GetRandomKey();
byte[] hash = new Rfc2898DeriveBytes(txtPassword.Text, salt)).GetBytes(20);
Session["test"] = GetString(hash);
Session["salt"] = GetString(salt);

Проверка

byte[] hash = GetBytes(Session["test"]);
byte[] salt = GetBytes(Session["salt"]);
byte[] output = new Rfc2898DeriveBytes(password, salt).GetBytes(20);
ltrResult.Text = GetString(hash).Equals(GetString(output)) ? "EQUAL" : "NOT EQUAL";
0 голосов
/ 15 ноября 2011

Вы можете сохранить соль в виде массива байтов в сеансе, чтобы не было различий в кодировке при преобразовании между строками и байтами:

byte[] SALT = GetRandomKey();
string password = Convert.ToBase64String((new Rfc2898DeriveBytes(txtPassword.Text, SALT)).GetBytes(20));
Session["test"] = password;
Session["salt"] = SALT;

и затем проверить, что данный парольсоответствует хешу, который вы повторяете ту же процедуру:

string HASHEDPASSWORD = Session["test"];
byte[] SALT = Session["salt"] as byte[];
string ouput = Convert.ToBase64String((new Rfc2898DeriveBytes(password, SALT)).GetBytes(20));
ltrResult.Text = HASHEDPASSWORD.Equals(ouput) ? "EQUAL" : "NOT EQUAL";
...