For the last 2 weeks I have been reading many blogs about website security and hashing passwords.
Many sites have mentioned the pro's and cons about different ways of doing this, which has left me a bit confused about how secure my code is.
If possible, can anyone have a look at the code below and let me know what they think. I have posted this question on https://codereview.stackexchange.com/questions/30814/hashing-passwords-for-website-is-this-secure but as off yet, no one has replied.
The steps I have took are as follows:
- Create random salt
- Add random salt and email together to create salt for password (email will be encrypted in database)
Hash password and salt and store in database
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); }