密码哈希
密码永远不应存储为纯文本! 应使用慢速密码散列算法对随机生成的盐进行散列(以抵御彩虹表攻击)。可以使用大量迭代(> 10k)来减缓暴力攻击。登录的用户可以接受~100ms 的延迟,但是难以破解长密码。选择多次迭代时,应使用应用程序的最大容许值,并随着计算机性能的提高而增加。你还需要考虑停止可能用作 DoS 攻击的重复请求。
当第一次散列时,可以为你生成 salt,然后可以将生成的散列和 salt 存储到文件中。
private void firstHash(string userName, string userPassword, int numberOfItterations)
{
Rfc2898DeriveBytes PBKDF2 = new Rfc2898DeriveBytes(userPassword, 8, numberOfItterations); //Hash the password with a 8 byte salt
byte[] hashedPassword = PBKDF2.GetBytes(20); //Returns a 20 byte hash
byte[] salt = PBKDF2.Salt;
writeHashToFile(userName, hashedPassword, salt, numberOfItterations); //Store the hashed password with the salt and number of itterations to check against future password entries
}
检查现有用户密码,从文件中读取其哈希值和 salt,并与输入密码的哈希值进行比较
private bool checkPassword(string userName, string userPassword, int numberOfItterations)
{
byte[] usersHash = getUserHashFromFile(userName);
byte[] userSalt = getUserSaltFromFile(userName);
Rfc2898DeriveBytes PBKDF2 = new Rfc2898DeriveBytes(userPassword, userSalt, numberOfItterations); //Hash the password with the users salt
byte[] hashedPassword = PBKDF2.GetBytes(20); //Returns a 20 byte hash
bool passwordsMach = comparePasswords(usersHash, hashedPassword); //Compares byte arrays
return passwordsMach;
}