Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

When adding salt values to a hash value for something like a password that cannot be stored in plain text, what is the best place to get the salt values come from? For context, let us suppose this is for passwords on a webpage login.

share|improve this question
    
Shouldn't it go to StackOverflow? A purely programming question. –  user8685 Feb 21 '11 at 18:54
    
@DevArt, I figured it was better suited here because it requires a very subjective answer. A salt value could be pulled from anywhere, so I am asking "Where do you think is the most secure location to pull salt values from: client or server?" –  Morgan Herlocker Feb 21 '11 at 19:03
add comment

5 Answers

up vote 4 down vote accepted

I usually have a column created TIMESTAMP in a user table so I can see when the user registered. I don't like to add an additional column for Salt, so I use the timestamp column as salt:

SHA1(password + created)
share|improve this answer
    
I am then assuming that when the user signs in again, you pull the date based on the username when you rehash for verification? –  Morgan Herlocker Feb 23 '11 at 19:13
1  
@Prof: Yes, in the same way as you do if you have a specific column for salt, so no difference in that perspective. –  Jonas Feb 23 '11 at 19:25
add comment

Does it matter?

The salt serves two purposes. It makes it impractical to use large tables of prehashed passwords ("rainbow tables") and it makes identical passwords look different in the list of hashes. Making the identical passwords look different helps avoid a problem where several people are using one particular password, which is presumably a common weak one.

Therefore, each account should have its own unique salt, and the salts should not be overly predictable, in the sense that there won't be a group of salts that are likely to occur. (If many sites started at 1 and counted up, bad guys could construct rainbow tables including low-number salts, for example.) They don't have to be random in any sense other than generally unpredictable. They aren't any more secret than the hash itself, so they don't need to be specifically unguessable.

Use any convenient method to generate a salt. If there's lots of potential salt values (early Unix systems frequently used two bytes, for a possible number of 65536) compared to the number of accounts, semi-random assignment would almost never give out a duplicate salt.

share|improve this answer
1  
I've generally seen the second issue-- identical passwords looking different-- addressed by concatenating the user name, the salt, and the password and hashing the whole string. That eliminates the need to generate a unique salt per account. –  Justin Cave Feb 21 '11 at 19:46
1  
@Justin: interesting, I had never seen the username used as part of the hash, but it's indeed a good way to add some entropy. I'd still use a pseudo-random salt though, just because it doesn't cost much to generate one. –  Matthieu M. Feb 21 '11 at 19:56
2  
@Matthieu With the downside of having to store it somewhere, and if both sides of a transaction need it, having to also send it. With the username, both sides already know it. –  Matthew Frederick Feb 21 '11 at 20:26
2  
@Justin: In which case you're using the user name as a salt. It answers both purposes of the salt: making rainbow tables impractical, and making similar passwords look different. –  David Thornley Feb 21 '11 at 21:12
    
@David - True, you can look at it as the user name becoming part of the salt. I'd still want an additional salt so that the attacker can't use a rainbow table to find the username/password combinations. Without an explicit salt, you're just increasing the size of the string the attacker needs from the rainbow table by the length of the username (which is likely to be short and either completely lower case or completely upper case). A constant salt is sufficient to thwart a rainbow table attack unless your site is large enough that an attacker would generate a site-specific rainbow table. –  Justin Cave Feb 21 '11 at 21:31
show 3 more comments

Each time you want to store a new password (registration, password-reset, password-update), one good technique is:

  • generate new salt
    • use a cryptographically-secure pseudo-random number generator
    • use a decent size salt - a good value is the block size of the underlying hash algorithm (might be SHA-256)
  • generate a new password token
    • create an hmac function from the underlying hash algorithm (might be SHA-256) using the salt as the hmac key
    • for i in (0...65536) { password = hmac(password) }
    • the result of the iterated applications of the hmac function is the password token
  • store the salt and the password token
    • do not store the original password
    • optionally store the underlying hash algorithm and the stretches for discoverability
share|improve this answer
add comment

Leverage the framework. In .NET you could use the RNGCryptoServoiceProvider...

        // If salt is not specified, generate it on the fly.
        if (saltBytes == null)
        {
            // Define min and max salt sizes.
            int minSaltSize = 4;
            int maxSaltSize = 8;

            // Generate a random number for the size of the salt.
            Random  random = new Random();
            int saltSize = random.Next(minSaltSize, maxSaltSize);

            // Allocate a byte array, which will hold the salt.
            saltBytes = new byte[saltSize];

            // Initialize a random number generator.
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();

            // Fill the salt with cryptographically strong byte values.
            rng.GetNonZeroBytes(saltBytes); 
        }

Other frameworks should have similar classes you can leverage. To achieve randomness software often times employs the user versus Random as mentioned above. Randomly moving a mouse around in a defined area to provide salt is an option employed by TrueCrypt. It boils down to your specific needs and level of security; since your salt could simply be !@#$%.

share|improve this answer
add comment

You generate a salt server-side and assign it to a user account upon its creation. Better use some crypto-generation API available with your framework but in principle any sequence will do.

Usually things are stored like this:

User
-------------------
ID
Username
PasswordHashWithSalt

Example:

PasswordHashWithSalt =

A15CD9652D4F4A3FB61A2A422AEAFDF0DEA4E703 j5d58k4b56s8744q

share|improve this answer
    
Assign it based on what though? Does it not have to come from some value that will remain in place so that it can be replicated when the user signs back in after creation? –  Morgan Herlocker Feb 21 '11 at 19:05
    
With "assign" I mean generate a salt per username/password pair (account) and store it in the database. When you need to perform login, you use that stored salt to check things. –  user8685 Feb 21 '11 at 19:07
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.