Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

A good way to salt password?
I have read a few answers related to salting password. But I started to get confused. I came across few functions people used to generate salt like:

So many functions out there, so which one I need use?


and one mini question:
What I know is salt must be as random as possible for each user's password. Currently I am using pseudo random bits (as in third in above list) to generate salt to bcrypt->hash(salt+password) and store the salt together with password in same row in mysql. Am I implement this wrong?

share|improve this question

3 Answers 3

up vote 7 down vote accepted

To be effective, a salt should be random (unpredictable) and unique (thus, a nonce). It doesn't have to be very long (though that doesn't hurt).

Your implementation is how a salt should be handled. However, bcrypt already includes a salt, so your efforts are a bit redundant. It definitely doesn't hurt anything, though.

share|improve this answer
    
Randomness is not necessary but it makes it easy to get uniqueness. –  Tom Leek Sep 6 '12 at 11:22
    
Randomness helps with collisions when you have a lot of hashes. Think password hashes of a milion users, when stored as descrypt (12 bit salt, 4096 maximum). There's gonna be many hashes that share a salt, thus lowering the level of effort to cracking them, which undoes the whole point of having a salt. If you only have only one hash total, it makes next to no difference how long the salt is. But for any non-trivial amount of hashes, long salts good, short salts bad. (Assuming their randomness is equally good) –  Marcin Sep 6 '12 at 14:29
    
Yes, but doesn't the uniqueness matter more than the randomness? My understanding of salting is that it is primarily designed to make it so that per-established tables can not be used for attempting to break a hash. As long as the salt value is different, then it should render table attacks useless. The main benefit I could see from randomness would be that it avoids the issue of salt overlap between systems (for example if company A started with a salt of 0000001 and so did company B, then most hackers would have tables for 00000001). Is this the only reason that randomness is desired? –  AJ Henderson Sep 6 '12 at 15:06
    
@AJHenderson Yes, exactly that. –  Jeff Ferland Sep 6 '12 at 15:49
    
although this answer is accepted, all answers below are great. So all 3 answers are accepted (implicitly XD) –  Tian Loon Sep 9 '12 at 21:07

Normally, if I recall correctly, Bcrypt has it's own built in salt. So you don't need to define your own salt as Bcrypt generates salts when hashing and stores them with the output.

From stackoverflow:

Stored in the database, a bcrypt "hash" might look something like this:

$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa

  • 2a identifies the bcrypt algorithm version that was used.
  • 10 is the cost factor; 210 iterations of the key derivation function are used (which is not enough, by the way. I'd recommend a cost of 12 or more.)
  • vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa is the salt and the cipher text, concatenated and encoded in a modified Base-64. The first 22 characters decode to a 16-byte value for the salt. The remaining characters are cipher text to be compared for authentication.
  • $ are used as delimiters for the header section of the hash.

This example is taken from the documentation for Coda Hale's ruby implementation.

share|improve this answer
    
It depends entirely on the used library, if Bcrypt creates it's own salt. If you use PHP's standard function crypt(), you will have to generate the salt by yourself. –  martinstoeckli Sep 6 '12 at 11:29
1  
@martinstoeckli You should NOT be using php crypt() to hash passwords anyway. Don't reinvent the wheel. If you are using php, use phpass. –  Terry Chia Sep 6 '12 at 12:11
    
Extra info: why bcrypt is better than PBKDF2 –  Tian Loon Sep 6 '12 at 12:17
    
@Terry Chia - I didn't recommend to use crypt(), but crypt() is the only native PHP function that implements Bcrypt, there is no function bcrypt() which generates the salt yet. So either you use a library and then it depends on the library, whether the salt is generated and how, or you have to generate it yourself. By the way, i strongly believe that one should understand how it works, and then one should use a well established library. –  martinstoeckli Sep 6 '12 at 12:53
1  
@martinstoeckli Even so, just use phpass. It is just one addition file to include, simple to use and very well documented and takes care of all the heavy lifting for you. Like i said, don't reinvent the wheel. –  Terry Chia Sep 6 '12 at 13:23

A salt must be unique. It does not have to be anything else (some password hashing algorithms have specific requirements on the length of the salt, but, in general, it is free-form).

Uniqueness should be understood worldwide and for all centuries. Ideally. Being unique to your server is not totally sufficient (an attacker could try to attack several servers at once, for the cost of attacking one). Being unique at a given time is not totally sufficient (e.g. if you reuse the salt whenever a user changes his password, an attacker could try to attack both the old and the new password for the cost of one password cracking effort).

An easy way to get the right sort of uniqueness is randomness. Being unpredictably random is not necessary for a salt, but if the salt is a sequence of at least 128 bits (16 bytes) which are obtained from a cryptographically strong PRNG, then you will get uniqueness "for free" with an overwhelming probability (and that's good enough).

(Unpredictable randomness is a requirement for other objects which are sometimes incorrectly called "salts", such as IV for CBC encryption; I assume that when you say "salt" you are really talking about password hashing.)

share|improve this answer
    
how do you call the unpredictable randomness? nonce? yes. password hashing. I have redundant salt, as Jeff Ferland said. Very great answer! I finally get an overview of the purpose of salt. Thanks –  Tian Loon Sep 6 '12 at 11:50
    
I'd argue that the salts should be random. Perhaps not cryptographically random, but random nonetheless. If the salt is very predictable, e.g. 000001 and increasing, an attacker might very well try to generate password hash tables in advance to attack admin accounts which usually are the first few accounts. –  Terry Chia Sep 6 '12 at 12:08
    
@TerryChia - yes, but then it would not be unique in the cryptographic sense of the term. Starting from 000001 is not unique unless nobody else is doing the same thing and never has done the same thing. –  AJ Henderson Sep 6 '12 at 15:17
    
@TerryChia: if every servers starts a counter at 1, then it is not unique worldwide -- and, precisely, it allows precomputing tables which will be applicable to several servers. However, if every server uses a counter which starts at a big random value, then the counter for a given server is very predictable, and yet you get worldwide uniqueness. Purely random salts are still easier than a server-wide counter, though (in particular with multi-frontend servers). –  Tom Leek Sep 7 '12 at 0:47
    
Out of curiousity, what about some globally-unique-but-not-random scheme, like concatenating your DNS name with a simple counter? E.g. security.stackexchange.com-0001. Obviously I would still recommend the simpler random value, but I'm curious how a scheme like this would hold up. –  AviD May 13 '13 at 11:13

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.