我正在提出某种思考问题。我为Xamarin.Forms应用程序创建了一个注册/登录系统。现在,当我注册一个帐户时,我会哈希密码并添加随机盐,但是对于登录我也是如此。问题是我需要获得与寄存器中使用的密码完全相同的盐。
这里是创建盐和香精的两个功能:
public String CreateSalt(int size)
{
var rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
var buff = new byte[size];
rng.GetBytes(buff);
return Convert.ToBase64String(buff);
}
public String GenerateSHA256Hash(String input, String salt)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(input + salt);
System.Security.Cryptography.SHA256Managed sha256hashstring =
new System.Security.Cryptography.SHA256Managed();
byte[] hash = sha256hashstring.ComputeHash(bytes);
return Convert.ToBase64String(hash);
}
这是我在注册和登录时使用的代码:
async void btnLogInClicked(object sender, EventArgs args)
{
string username = txtUsername.Text;
string password = txtPassword.Text;
string salt = CreateSalt(16);
string HashedPassword = GenerateSHA256Hash(password, salt);
HashedPassword = HashedPassword.Replace('+', '-');
HashedPassword = HashedPassword.Replace('/', '_');
User user = new User
{
Username = username,
Password = HashedPassword
};
var result = await App.RestService.Login(user);
if (result != null)
{
App.Current.MainPage = new SideMenuItems();
}
}
我该怎么做,仍然对每个新生成的密码使用随机盐?
似乎每年我都必须重新学习如何正确地对密码进行哈希处理。我就是这样做的,我会尽力在这里解释。
您的问题是,当用户登录时,每次调用CreateSalt
时都会生成新的盐。如注释中所述,您希望在注册期间生成一次盐和哈希,然后将它们保存到数据库中。
然后,当用户登录时,您可以从数据库中检索盐,并将其与用户输入的密码一起使用以生成哈希。最后,将新生成的哈希与数据库中保存的哈希进行比较,以查看密码是否正确。
我建议使用慢速哈希算法,而不要使用SHA256来生成哈希。 PBKDF2将是一个不错的选择,并且内置.NET作为Rfc2898DeriveBytes类。另一个流行的选择是bcrypt。它需要.NET中的第三方库,但我发现它很容易实现(至少使用Node)。有关密码哈希算法here的更多常规信息。
最后要考虑的是算法使用的迭代次数。 Rfc2898DeriveBytes
类具有一些构造函数,其中之一设置了默认的1000次迭代,这足够了。迭代(或“成本”)减慢了哈希函数的速度,有助于阻止攻击。