检查登录ASP.NET Core上的加密密码



我有一种加密用户密码的方法,如下所示:

public string EncryptPassword(string password)
{
// Encrypt password
byte[] salt = new byte[128 / 8]; // Generate a 128-bit salt using a secure PRNG
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
string encryptedPassw = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: salt,
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8
));
return encryptedPassw;
}

但我遇到了一个问题:我想让用户登录,但我不知道如何在登录时正确读取密码。知道如何解决或遇到同样问题的人能帮忙吗。

如何将盐与用户一起存储?

只需向用户添加一个属性,如下所示:

public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Password { get; set; }
public byte[] StoredSalt { get; set; }
//other properties...
}

当用户输入新密码时,您需要使用相同的salt对其进行加密,然后将其与数据库中的加密密码进行比较。

您可以参考以下代码:

定义一个临时使用的新类:

public class HashSalt
{
public string Hash { get; set; }
public byte[] Salt { get; set; }
}

类似于注册和登录:

[HttpPost]
public IActionResult Register(User user)
{
var hashsalt = EncryptPassword(user.Password);
user.Password = hashsalt.Hash;
user.StoredSalt = hashsalt.Salt;
_context.Users.Add(user);
_context.SaveChanges();
return View();
}
[HttpPost]
public IActionResult Login(User loginUser)
{
var user = _context.Users.FirstOrDefault(u => u.Name == loginUser.Name);
var isPasswordMatched = VerifyPassword(loginUser.Password, user.StoredSalt, user.Password);
if (isPasswordMatched)
{
//Login Successfull
}
else
{
//Login Failed
}
return View();
}
public HashSalt EncryptPassword(string password)
{
byte[] salt = new byte[128 / 8]; // Generate a 128-bit salt using a secure PRNG
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(salt);
}
string encryptedPassw = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: password,
salt: salt,
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8
));
return new HashSalt { Hash = encryptedPassw , Salt = salt };
}

public bool VerifyPassword(string enteredPassword, byte[] salt, string storedPassword)
{
string encryptedPassw = Convert.ToBase64String(KeyDerivation.Pbkdf2(
password: enteredPassword,
salt: salt,
prf: KeyDerivationPrf.HMACSHA1,
iterationCount: 10000,
numBytesRequested: 256 / 8
));
return encryptedPassw == storedPassword;
}

如果目标是在身份验证之前验证密码,则无需解密保存的密码,而是加密输入的密码,以便比较对应关系。

//...
if(EncryptPassword(enteredPwd)==encryptedSavedPwd){
//authentication
}else{
//password error
}

同意@elgsylvain85,用户登录时无需解密密码即可验证凭据。您可以加密用户输入的密码,并将其与数据存储进行匹配。

也就是说,存储密码的最佳做法是哈希而不是加密。即使黑客能够访问数据存储,哈希密码也无法解码。

以下是.NET哈希的文档。https://learn.microsoft.com/en-us/dotnet/standard/security/ensuring-data-integrity-with-hash-codes

最新更新