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 http://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);
}