Хеш пароля не совпадает

Я не могу войти в систему, потому что пароль Hash не совпадает. Что я делаю неправильно. Мой сервер sql, на котором хранится хэш пароля, имеет тип данных nvarchar. Раньше я использовал двоичный тип данных, но это не сработало.

 private readonly MovieHubContext _context;
    public AuthRepository(MovieHubContext context)
    {
        _context = context;
    }

    //method is called when the user hits the login button
    public async Task<Users> Login(string username, string password)
    {
        //returns the username from the databse
        var user = await _context.Users.FirstOrDefaultAsync(x => x.UserName == username);
        if (user == null)
        {
            return null;
        }

        if (!VerifyPasswordHash(password, System.Text.Encoding.UTF8.GetBytes(user.PasswordHash),
            System.Text.Encoding.UTF8.GetBytes(user.PasswordSalt)))
            return null;
        return user;

    }
    // this method is used to verify the password 
    private bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt)
    {
        using (var hmac = new System.Security.Cryptography.HMACSHA512(passwordSalt))
        {
            //changes the string into byte and them computes the hash
            byte[] computedHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
            for (int i = 0; i < computedHash.Length; i++)
            {
                //compares the hashed password(user input) with the hashed password from the database
                if (computedHash[i] != passwordHash[i])
                    return false;
            }
        }
        return true;
    }
    // This method is used to register the users
    public async Task<Users> Register(Users users, string password)
    {
        byte[] passwordHash, passwordSalt;
        CreatePasswordHash(password, out passwordHash, out passwordSalt);

        users.PasswordHash = System.Text.Encoding.UTF8.GetString(passwordHash);
        users.PasswordSalt = System.Text.Encoding.UTF8.GetString(passwordSalt);

        //save into database
        await _context.Users.AddAsync(users);
        await _context.SaveChangesAsync();

        return users;


    }

    private void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt)
    {
        using (var hmac = new System.Security.Cryptography.HMACSHA512())
        {
            passwordSalt = hmac.Key;
            passwordHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
        }
    }

    public async Task<bool> UserExists(string username)
    {
        if (await _context.Users.AnyAsync(x => x.UserName == username))
            return true;

        return false;
    }

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
566
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Просто замените UTF8.GetBytes на Convert.FromBase64String и UTF8.GetString на Convert.ToBase64String после регистрации / проверки.

public async Task<Users> Register(Users users, string password)
{
    byte[] passwordHash, passwordSalt;
    CreatePasswordHash(password, out passwordHash, out passwordSalt);

    users.PasswordHash = Convert.ToBase64String(passwordHash);
    users.PasswordSalt = Convert.ToBase64String(passwordSalt);

    //save into database
    await _context.Users.AddAsync(users);
    await _context.SaveChangesAsync();

    return users;
}

а также

public async Task<Users> Login(string username, string password)
{
    //returns the username from the databse
    var user = await _context.Users.FirstOrDefaultAsync(x => x.UserName == username);
    if (user == null)
    {
        return null;
    }

    if (!VerifyPasswordHash(password, Convert.FromBase64String(user.PasswordHash),
        Convert.FromBase64String(user.PasswordSalt)))
        return null;
    return user;

}

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

Просто распечатайте эти строки, чтобы увидеть, что у вас получится.

Напротив, кодировка base64 обеспечивает преобразование байтовых массивов в строки безопасно в том смысле, что вы можете безопасно хранить / извлекать их.

Вот рабочий пример слегка измененной версии (async и dbcontext удалены),

https://dotnetfiddle.net/fH5mXh

Большое тебе спасибо. Я спотыкался о преобразовании данных. Ваше объяснение ясно.

Not Applicable 08.10.2018 23:13
Ответ принят как подходящий

введите код здесь У меня была такая же проблема, потому что я хранил данные в двоичном типе данных (64) на сервере sql, затем я меняю

        public async Task<User> Login(string username, string password)
    {
        var user = await _context.Users.FirstOrDefaultAsync(x => x.Username == username);
        if (user == null)
        return null;
        if (!VerifyPasswordHash(password, user.PasswordHash, user.PasswordSalt))
        return null;

        return user;
    }
    public async Task<User> Register(User user, string password)
    {
        byte[] passwordHash, passwordSalt;
        CreatePasswordHash(password, out passwordHash, out passwordSalt);
        user.PasswordHash = passwordHash;
        user.PasswordSalt = passwordSalt;

        await _context.Users.AddAsync(user);
        await _context.SaveChangesAsync();

        return user;
    }
    private void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt)
    {
        using (var hmaic = new System.Security.Cryptography.HMACSHA512())
        {
          passwordSalt = hmaic.Key;
          passwordHash = hmaic.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
        }
    }
    private bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt)
    {
       using (var hmaic = new System.Security.Cryptography.HMACSHA512(passwordSalt))
        {             
          var computedHash = hmaic.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));

          for(int i =0; i < computedHash.Length; i++)
          {
              if (computedHash[i] != passwordHash[i])
              return false;
          }

          return true;
        }

    }

Не могли бы вы подробнее рассказать о том, что вы изменили?

THess 13.02.2020 11:11

Другие вопросы по теме