bcrypt: random salt vs computed salt

You do not want to use a fixed salt for a given user because it could lead to salt reuse, which is bad (that's the capital sin of salts, since the whole idea of salts is not to be reused; they have no other function). Salt reuse can occur, practically, for the two following reasons:

  • If a user changes his password, the new password will use the same salt than the old. That's bad, because old passwords are still valuable (since users reuse passwords, the old password can be the password that the user will set next month; it can also be the password for the same user on another site), and the reuse will allow the attacker to attack both the old and new password for the cost of one brute force.

  • If the salt is derived from the user name, then another instance of the server software, on a distinct server, may end up with the same salts, because "Administrator" tends to always be called "Administrator". Attackers could precompute a big table (e.g. rainbow table) for "Administrator", applicable to many sites (which would make table building worth the effort).

I usually sum this up by stating that salts must be unique timewise (no reuse of an old salt value) and worldwide (no reuse of salts anywhere, even on a distinct server). Such uniqueness is hard to get, but there is nonetheless a rather simple way, which is to generate big enough salts (e.g. 128-bit salts, as bcrypt uses) at random.

Summary: not generating bcrypt salts randomly would not be more secure; at best, this would be equally secure, but, more probably, less secure.


The reason for a salt is, to prevent attacks with pre calculated rainbow tables. The attacker would have to build one rainbow table for each password, and that doesn't make sense (it's easier to brute-force until you found a match). So the job of the salt is done, even when it is visible plaintext in the hash-value.

If you want to add a secret to the calculation, then you can add an additional pepper. In contrast to the salt, the pepper will not be stored in the database. This will help against dictionary attacks, as long as the attacker has only access to your data (e.g. SQL-Injection) but not to your code.

I would not mix up salt and pepper, because they serve a different purpose. And to answer your question, use a random salt, and add a pepper if you want to add something hidden.