Password Hashing

An overview over the password hashing algorithms supported by Silhouette and how they can be used

How to use

Sometimes it's needed to change the password hashing algorithm, because of a better algorithm or some similar case. But the passwords stored in the backing store cannot easily be converted with another algorithm because they're hashed and cannot be decrypted back to plain text. For such case Silhouette supports the change of hashing algorithms on the fly. So if a user successfully authenticates after the application has changed the hashing algorithm, the provider hashes the entered plain-text password again with the new algorithm and overrides the auth info in the backing store with the new hash.

The password hasher registry defines the current password hasher which is able to hash all new passwords and also match the passwords stored in the backing store for this algorithm. And also a list of deprecated hashers, which should match passwords that are stored in the baking store but which are different to the current hasher.

PasswordHasherRegistry(
  current = new BCryptSha256PasswordHasher(), 
  deprecated = Seq(new BCryptPasswordHasher())
)

Algorithms

Bcrypt

Bcrypt is a popular password hashing algorithm, which hashes passwords using a version of Bruce Schneier's Blowfish block cipher with modifications designed to raise the cost of off-line password cracking. The computation cost of the algorithm is parameterized, so it can be increased as computers get faster.

The hasher uses JBCrypt as underlying implementation, so there is no need to install additional dependencies.

The implementation is provided by the classes BCryptPasswordHasher and BCryptSha256PasswordHasher. The constructor of both classes takes an optional parameter logRounds that determines the computational complexity of the hashing. The amount of work increases exponentially (2**logRounds), so each increment is twice as much work. The default logRounds is 10, and the valid range is 4 to 31.

🚧

Password truncation with BCryptPasswordHasher

The designers of bcrypt truncate all passwords at 72 characters which means that bcrypt(password_with_100_chars) == bcrypt(password_with_100_chars[:72]). The original BCryptPasswordHasher does not have any special handling and thus is also subject to this hidden password length limit. BCryptSha256PasswordHasher fixes this by first hashing the password using sha256. This prevents the password truncation and so should be preferred over the BCryptPasswordHasher. The practical ramification of this truncation is pretty marginal as the average user does not have a password greater than 72 characters in length and even being truncated at 72 the compute powered required to brute force bcrypt in any useful amount of time is still astronomical. Nonetheless, we recommend you use BCryptSha256PasswordHasher anyway on the principle of "better safe than sorry".