Health Check: Passwords with salt and hash

I had an idea about hashed passwords and salt values. Since I'm pretty new to hashing and encryption, I thought I'd send this to you. Would it be safer to create a unique salt for each user account and then store the salt and hash values ​​in the database? Or, save one salt value that will be stored and reused every time I keep the password?

For example, the user will use a password:

"secret" 

My code will generate a salt value:

 "d1d0e3d4b3d1ed1598a4e77bb614750a2a175e" 

Then we get the result:

 "e8187dcbe8e2eabd4675f3a345fe21c98affb 5544a9278461535cb67265b6fe09a11dbef572 ce3a4a8f2275839927625cf0bc7bc46fc45d51 12d7c0713bb4a3" 

The hashed result and salt will then be stored in the database in the user profile when their account has been created. Then, every time a user logs in, a new salt is generated, the password and salt are re-displayed and stored in the database.

Any thoughts? As I said, this is a sanity check about my idea.

+4
source share
4 answers

Storing unique salt per user is a good idea, in my opinion. Re-generating the salt / hash combination every time a user logs in is a little pointless if you don't have processor cycles to write to. I would recommend using something like the Rfc2898DeriveBytes class to create a safe salt / hash combination:

A simple example of creating a password hash:

 string password = GetPasswordFromInput(); using (var deriveBytes = new Rfc2898DeriveBytes(password, 32)) // 32-byte salt { byte[] salt = deriveBytes.Salt; byte[] hash = deriveBytes.GetBytes(32); // 32-byte hash SaveToDatabase(salt, hash); } 

And the corresponding password check:

 string password = GetPasswordFromInput(); byte[] salt = GetSaltFromDatabase(); byte[] hash = GetHashFromDatabase(); using (var deriveBytes = new Rfc2898DeriveBytes(password, salt)) { if (deriveBytes.GetBytes(32).SequenceEqual(hash)) Console.WriteLine("Password matches"); else throw new Exception("Bad password"); } 
+6
source

As Adam already mentioned, hashing and storing a password every time a user logs in does not have a real purpose.

Instead of skating yourself, you may need to use BCrypt.NET , the .NET implementation of the proven password hashing algorithm,

Using is very simple:

 // When setting password string hashedPassword = BCrypt.HashPassword(password, BCrypt.GenerateSalt()); // Upon login bool validPassword = BCrypt.CheckPassword(password, hashedPassword); 

This allows you to vary the computational cost of computing the password hash if you want, which makes it difficult for someone to perform a dictionary attack on a database that they could get, for example. This is done by adding a parameter to the call to the GenerateSalt method.

Details of the BCrypt algorithm can be found here .

+4
source
  • Each user must have their own unique salt.
  • It makes no sense to update the salt every time the user logs in, it does not have a real security goal.
  • The salt must be randomly generated and is not connected in any way with a password.

The purpose of the salt is to protect against pre-calculated attacks (such as rainbow tables). Therefore, if two users have the same password, they will not have the same final hash. If the salt is systemic and not for the user, then this is not so, and the attacker only needs to pre-calculate all the passwords for your system once. If each user has his own salt, then for each user it is necessary to carry out an attack with preliminary calculation, making the attack impossible.

Using a salt hash does not protect against brute force attacks. You will need to use other methods to protect against them.

+3
source

The real purpose of the salt is to prevent against electoral attacks, since the salt itself should NOT be secret (i.e. it is good that it is accessible from the outside world). Therefore, it is not intended to provide security against coarse forcing, since it is (almost) easily processed by the hash (Salt + Password), since it hash (Password).

If you think that someone will actually build a pre-computed table of your only salt in the password database, and then look at the salted password hashes that they found in your database with the specified table, then you should use a unique salt for each password. Otherwise, do not worry about it.

+1
source

All Articles