在过去的两周里,我阅读了许多关于网站安全和散列密码的博客。
许多网站都提到了不同方法的优缺点,这让我对我的代码的安全性有点困惑。
如果可能的话,任何人都可以看看下面的代码,让我知道他们的想法。我已经在https://codereview.stackexchange.com/questions/30814/hashing-passwords-for-website-is-this-secure上发布了这个问题,但到目前为止,还没有人回复。
我采取的步骤如下:
- 创建随机盐
- 将随机盐和电子邮件一起添加以创建密码盐(电子邮件将在数据库中加密)
哈希密码和盐并存储在数据库中
public const int HashBytes = 128; public const int DefaultIterations = 10000; //Create random bytes for salt public static string SaltSHA256() { const int minSaltSize = 8; const int maxSaltSize = 16; var random = new Random(); int saltSize = random.Next(minSaltSize, maxSaltSize); byte[] saltBytes = new byte[saltSize]; var rng = new RNGCryptoServiceProvider(); rng.GetNonZeroBytes(saltBytes); HashAlgorithm hash = new SHA256Managed(); byte[] bytes = hash.ComputeHash(saltBytes); return Convert.ToBase64String(bytes); } //Create salt using email and public static string SaltSHA256() //Store email and public static string SaltSHA256() in database public static string SaltRfc2898(string email,string hashedSalt) { var salt = new Rfc2898DeriveBytes(email, Encoding.UTF8.GetBytes(hashedSalt), DefaultIterations); return Convert.ToBase64String(salt.GetBytes(HashBytes)); } //Hash password and salt public static string PasswordHashRfc2898(string password,string salt) { var hashedPassword = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(salt), DefaultIterations); return Convert.ToBase64String(hashedPassword.GetBytes(HashBytes)); } //Get salt and password from database based on username //Salt in from data created by public static string SaltSHA256() public static bool DoPasswordsMatch(string password,string salt) { //Password would be pulled from db based on username byte[] testPassword = Convert.FromBase64String("basestring"); //Salt would be pulled from database based on username var saltFromDatabase = salt; //Hash password and salt var hashUserInputAndSalt = PasswordHashRfc2898(password, saltFromDatabase); //Convert to byte[] ready for comparison byte[] convertUserInputFromBase64 = Convert.FromBase64String(hashUserInputAndSalt); //Compare and return true or false return convertUserInputFromBase64.SequenceEqual(testPassword); }