-
Couldn't load subscription status.
- Fork 34
BCrypt
bcrypt is a password-hashing function, based on the Blowfish cipher. Besides incorporating a salt to protect against rainbow table attacks, bcrypt is an adaptive function: over time, the iteration count can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power.
bcrypt accepts 2 parameters: the version of the algorithm (a, x, y or b) and the cost factor, that is the number of rounds in logarithmic form (e.g. cost factor of 10 means 210 = 1024 rounds).
| Name | Default value | Properties | Description |
|---|---|---|---|
| Version | b | hash.bcrypt.minor |
Defines the minor version of bcrypt |
| Cost factor | 10 | hash.bcrypt.rounds |
Defines the number of rounds expressed as exponent of base 2 |
The suggested version of the algorithm is b, the latest one. The other versions should be used only for backward compatibility reasons and we recommend to update your hashes as soon as possible.
You can define a singleton custom bcrypt function by calling BCryptFunction.getInstance(BCrypt, int) or BCryptFunction.getInstance(int)
BcryptFunction bcrypt = BcryptFunction.getInstance(Bcrypt.Y, 11);In this case you have created a singleton instance which uses version y of bcrypt and has a cost factor of 211 = 2048.
Alternatively if you have defined the parameters in the psw4j.properties file
BcryptFunction bcrypt = AlgorithmFinder.getBcryptInstance();Additionally you can create a BcryptFunction singleton instance from the hash, since all the parameters required are stored into it.
String hashed = "$2y$06$9JujYcoWPmifvFA3RUP90e5rSEHAb5Ye6iv3.G9ikiHNv5cxjNEse";
BcryptFunction bcrypt = BcryptFunction.getInstanceFromHash(hashed);Hashing passwords with bcrypt can be done quite easily.
Hash hash = Password.hash(plainTextPassword).withBcrypt();
hash.getResult(); // $2b$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfSThis approach takes the parameters from psw4j.properties file (like AlgorithmFinder.getBCryptInstance()).
However it's possible to use user-defined parameters as we saw previously
BcryptFunction myBcrypt = BcryptFunction.getInstance(Bcrypt.Y, 11);
Password.hash(plainTextPassword).with(myBcrypt);bcrypt calculates the salt by its own depending on the algorithm's parameters and it is not possible to specify a custom salt in order to avoid inconsistencies.
Method addPepper(CharSequence) make you define the intended pepper.
Hash hash = Password.hash(plainTextPassword).addPepper("AlicePepper").withBCrypt();Alternatively you can define the pepper in the psw4j.properties file at the property global.pepper
Hash hash = Password.hash(plainTextPassword).addPepper().withBCrypt();The pepper is always prepended.
Ideally the hash is retrieved from the database. Once retrieved you can check the user-provided passwords against the hash from your database. The salt is always encoded within the hash.
String hashFromDB = getHashFromDatabase(user);
boolean verified = Password.check(userProvidedPassword, hashFromDB).withBcrypt();The parameters used are taken from your psw4j.properties file.
Alternatively you can define your own parameters
String hashFromDB = getHashFromDatabase(user);
BcryptFunction myBcrypt = BcryptFunction.getInstance(Bcrypt.Y, 11);
boolean verified = Password.check(userProvidedPassword, hashFromDB).with(myBcrypt);If you want to migrate your cryptographic hashes from the original configuration to a more secure one, you can refresh them during the first user login.
String hashFromDB = getHashFromDatabase(user);
BcryptFunction myBcrypt = BcryptFunction.getInstance(Bcrypt.B, 12);
HashUpdate update = Password.check(userProvidedPassword, hashFromDB)
.andUpdate()
.addNewRandomSalt().with(myBcrypt);
if(update.isVerified())
{
Hash newHash = update.getHash();
storeNewHash(user, newHash.getHash());
}You can switch to any other hashing function offered by Password4j (for example Argon2)
BcryptFunction oldFunction = BCryptFunction.getInstance(Bcrypt.A, 10);
Argon2Function newFunction = AlgorithmFinder.getArgon2Function();
HashUpdate update = Password.check(userProvidedPassword, hashFromDB)
.andUpdate()
.addNewRandomSalt().with(oldFunction, newFunction);