Basically, bcrypt randomly generates a long, probably-unique salt for every hashed password, and the salt is stored along with the hash by simply concatenating it to the string (e.g. “randomsaltZdR3/passwordhashMP2tA”). To check an incoming password against the stored hash, bcrypt splits the stored string on ‘/’ to extract the salt, hashes `password+salt`, and compares that hash against the one to the right of ‘/’ in the stored string.
The PHP function produces output compatible with the crypt() function, which has not only the salt and the hash, but also includes the type of algorithm and the bcrypt cost.
This means that you just whack the hash and the password the user entered into password_verify(...) and it will tell you if you have a match - you don't have to keep track of the four parameters.
The beauty of that when a stronger algorithm comes out or you want to increase the cost factor of your passwords, you just change the hashing code and you don't have to do anything fancy to not break all your old hashes.
You can also use the password_needs_rehash(...) function once you verify to see if you should rehash the password to bring it up to the new level.
In general, using the defaults (mcrypt_create_iv() using dev/urandom for the salt and bcrypt with a work factor of 10 are specified with PASSWORD_DEFAULT in the curreent implementation) along with password_needs_rehash() will keep you up to date with no "retouch" necessary. When the default changes, password_needs_rehash() returns true, and you then rehash with the new defaults. All you need to do is make the db column wider than necessary for the current defaults to put maintenance off into the future. (The only real problem is that the hash function truncates passwords at 72 characters at the moment, which will force you to pre-hash the user value with something like SHA256 for very long passphrases.)
I don't think it's bcrypt that does it. It's the underlying implementation of bcrypt chooses to do it for the users. Or does the actual bcrypt standard says implementation has to generate one for user?
It seems that bcrypt does not specify that salts are randomly generated, but it does specify that the salt is stored with the hash. The “Bcrypt Algorithm” section of the paper at https://www.usenix.org/legacy/publications/library/proceedin... shows salts to be an input to the algorithm, and also describes them being concatenated with the hash. Random generation of the salt must be just a de-facto standard for bcrypt APIs. It’s true that that feature is orthogonal to the hashing function, and so libraries for other hashing algorithms could easily copy it.
I think the part concat with salt is required. But generating it FOR the user is orthogonal to the hashing function. But I will be surprise if the paper actually says it is required to generate one - because that shows the cleverness of the inventors, but also a potential weakness (implementation may be using weak random source, though counter-argument is that user supplied salt can be weak too).
Basically, bcrypt randomly generates a long, probably-unique salt for every hashed password, and the salt is stored along with the hash by simply concatenating it to the string (e.g. “randomsaltZdR3/passwordhashMP2tA”). To check an incoming password against the stored hash, bcrypt splits the stored string on ‘/’ to extract the salt, hashes `password+salt`, and compares that hash against the one to the right of ‘/’ in the stored string.