Password Hashing C# with Example
Passwords should never be stored as plain text! They should be hashed with a randomly generated salt (to defend against rainbow table attacks) using a slow password hashing algorithm. A high number of iterations (> 10k) can be used to slow down brute force attacks. A delay of ~100ms is acceptable to a user logging in, but makes breaking a long password difficult. When choosing a number of iterations you should use the maximum tolerable value for your application and increase it as computer performance improves. You will also need to consider stopping repeated requests which could be used as a DoS attack. When hashing for the first time a salt can be generated for you, the resulting hash and salt can then be stored to a file. 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 } Checking an existing users password, read their hash and salt from a file and compare to the hash of the entered password 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; }