Pre-hash password before applying bcrypt to avoid restricting password length

Using a secure hash function to preprocess the password is secure; it can be shown that if bcrypt(SHA-256(password)) is broken, then either the password was guessed, or some security characteristic of SHA-256 has been proven false. There is no need to fiddle with the salt at that level; just hash the password, then use bcrypt on the result (with the salt, as bcrypt mandates). SHA-256 is considered to be a secure hash function.

The point of a salt is to be unique -- as unique as possible, so that no two hashed passwords use the same salt value. 32 bits are a bit low for that; you should use a longer salt. If you have n bits of salt, then you will encounter collisions (two hashed passwords using the same salt) as soon as you have more than about 2n/2 hashed passwords -- that's about 65000 with n = 32, a not too high value. You'd better use 64 bits or more of salt (use 128 bits and you can cease to worry about it).


Bcrypt uses a 128-bit salt AND a 55 character (max) password. You do not need to add any other salt values; bcrypt handles that.

The designers of bcrypt felt that the 55 character limit on the password wasn't an issue since the hash has a 128-bit output. If your password is greater than 55 characters, the designers assumed that you are already providing more than 128-bits of entropy so this isn't a problem. On the contrary, the NIST guidelines would count this as only 77 bits of entropy. The NIST guidelines are based on the fact that pass phrases have less entropy per character than random passwords and on the assumption that users will use pass phrases for longer passwords. To better ensure that you get a full 128-bits of entropy, you could allow longer passwords and hash them using SHA-256 or SHA-384 to compress them to an acceptable length. You could also just simplify things by using scrypt or PBKDF2 which do not have length limitations. Scrypt is designed to be "memory hard" in addition to being computationally time-consuming; that would be my choice of algorithms.