Does salt need to be random to secure a password h

2019-06-17 01:23发布

问题:

I know very little about security (I need to find a basic explanation of the basics) and am trying to come up with a reasonable way to store user passwords in a database using .Net.

Here's my current solution:

private static byte[] HashPassword(string password)
{
   using (var deriveBytes = new Rfc2898DeriveBytes(password, 10))
   {
      byte[] salt = deriveBytes.Salt;
      byte[] key  = deriveBytes.GetBytes(20);

      return salt.Concat(key).ToArray();  //Return Salt+Key
   }
}

I store the results of HashPassword() in the database. To check a user's password I do this:

var salt = //1st  10 bytes stored in the DB
var key  = //Next 20 bytes stored in the DB 
using (var deriveBytes = new Rfc2898DeriveBytes(password, salt))
{
   byte[] newKey = deriveBytes.GetBytes(20);

   if (newKey.SequenceEqual(key) == false)  //Check if keys match
   {
      return "No Match";
   }
   else { return "Passwords match"; }

My question is if the salt needs to be random and stored in the DB like this or if I could generate a 10-byte salt and store it in my code and always use the same salt to save myself storing the salt in the DB and just store the key?

Also if anyone sees any other problems with what I'm doing I'd appreciate any advise.

回答1:

My question is if the salt needs to be random and stored in the DB like this or if I could generate a 10-byte salt and store it in my code and always use the same salt to save myself storing the salt in the DB and just store the key?

ABSOLUTELY NOT.

You don't understand at all the purpose of the salt if you're even asking that question.

The purpose of the salt is to make it arbitrarily more difficult for an attacker to use a precomputed table of hashed common passwords. If the salt is always the same then the attacker just precomputes a table of hashed common passwords with that salt.

Let me make that more clear. Suppose an attacker has obtained your password database and is mounting an attack at her leisure against all the stored hashes to work out what the password corresponding to the hash is. If every salt is different then the attacker has to mount a fresh attack against every entry in the database. If every salt is the same then attacking one user attacks every user.

Moreover: suppose you use the same salt for every user. Suppose two users have the same password. And suppose the attacker has obtained the password database. The attacker now knows which two users have the same password because they have the same salted hash and can make the reasonable assumption that this is the weakest password in the database. The attacker can concentrate her efforts (whatever those may be) on attacking that user in particular. And once she knows that user's password, odds are good that the user has used that user name and weak password on other systems, which the attacker can now compromise without having their password files.

It is good that you want to learn about security; it is bad that you're trying to write a real password system with your level of understanding. If this is for a real system that has to protect real users, use a system built by experts, or hire your own expert. You're going to make a system that you can't break, not a system that an attacker can't break.

Moreover: you are asking strangers on the internet for help with security. Strangers who you have no idea whether they know what they're talking about or are just making stuff up. Get a real security expert (and that is not me -- I'm an expert on semantic analyzers). Building a security system is one of the hardest programming tasks there is; you need professional help.

For a gentle introduction to basic password authentication schemes, see my series of articles:

http://blogs.msdn.com/b/ericlippert/archive/tags/salt/



回答2:

You don't need to apply a random salt, but if you do your passwords will be that bit more secure. Obviously, if you do apply a random salt then you need to store that with the hashed password in the db so that you can check against a supplied password.

A quick google revealed this post, which may help you out.