Я не могу войти в систему, потому что пароль 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;
}
Это код, который я написал для регистрации и входа в систему моего клиента. Я не могу понять, что делаю не так.





Просто замените 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
введите код здесь У меня была такая же проблема, потому что я хранил данные в двоичном типе данных (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;
}
}
Не могли бы вы подробнее рассказать о том, что вы изменили?
Большое тебе спасибо. Я спотыкался о преобразовании данных. Ваше объяснение ясно.