SkillAgentSearch skills...

Bcrypt

A Java standalone implementation of the bcrypt password hash function. Based on the Blowfish cipher it is the default password hash algorithm for OpenBSD and other systems including some Linux distributions. Includes a CLI Tool.

Install / Use

/learn @patrickfav/Bcrypt

README

Bcrypt Java Library and CLI Tool

This is an implementation of the OpenBSD Blowfish password hashing algorithm, as described in "A Future-Adaptable Password Scheme" by Niels Provos and David Mazieres. It's core is based on jBcrypt, but heavily refactored, modernized and with a lot of updates and enhancements. It supports all common versions, has a security sensitive API and is fully tested against a range of test vectors and reference implementations.

Maven Central Github Actions libs.tech recommends Javadocs Coverage Security Rating Maintainability Rating

The code is compiled with target Java 7 to be compatible with most Android versions as well as normal Java applications.

Quickstart

This library is published to Maven Central

Add the dependency of the latest version to your pom.xml:

<dependency>
    <groupId>at.favre.lib</groupId>
    <artifactId>bcrypt</artifactId>
    <version>{latest-version}</version>
</dependency>

Or if you are using Gradle:

implementation("at.favre.lib:bcrypt:{latest-version}")

A simple example:

String password = "1234";
String bcryptHashString = BCrypt.withDefaults().hashToString(12, password.toCharArray());
// $2a$12$US00g/uMhoSBm.HiuieBjeMtoN69SN.GE25fCpldebzkryUyopws6
    ...
BCrypt.Result result = BCrypt.verifyer().verify(password.toCharArray(), bcryptHashString);
// result.verified == true

API Description for the Java Library

The following APIs are for advanced use-cases and require the developer to be familiar with the material. If you are not sure, just stick to the quick start example.

Bcrypt Versions

This implementation supports the various versions, which basically only differ through their identifier:

char[] bcryptChars = BCrypt.with(BCrypt.Version.VERSION_2Y).hashToChar(6, password.toCharArray());
// $2y$06$doGnefu9cbLkJTn8sef7U.dynHJFe5hS6xp7vLWb2Zu7e8cOuMVmS

char[] bcryptChars = BCrypt.with(BCrypt.Version.VERSION_2B).hashToChar(6, password.toCharArray());
// $2b$06$GskjDDM9oejRN8pxNhiSZuIw/cnjbsNb8IfWGd3TFQXtRfKTN95r.

For example the PHP implementation of bcrypt will return hashes with version $2y$. By using BCrypt.withDefaults() it will default to version $2a$. The older $2$ version is not supported. For advanced use cases you may add your own version by providing a version identifier and a custom message formatter as well as parser.

Version customVersion2f = new Version(new byte[]{0x32, 0x66} /* 2f */, true, true, myCustomFormatter, myCustomParser);

byte[] vs char[] API

You can use either char[] or byte[] as input or output parameter. The reason String is usually omitted in security relevant APIs is, that a primitive array can usually be overwritten, as to discard it immediately after use. It is however not possible to wipe the content of the immutable String. The encoding always defaults to UTF-8.

byte[] bcryptHashBytes = BCrypt.withDefaults().hash(6, password.getBytes(StandardCharsets.UTF_8));
    ...
BCrypt.Result result = BCrypt.verifyer().verify(password.getBytes(StandardCharsets.UTF_8), bcryptHashBytes);

and

char[] bcryptChars = BCrypt.withDefaults().hashToChar(12, password.toCharArray());
    ...
BCrypt.Result result = BCrypt.verifyer().verify(password.toCharArray(), bcryptChars);

Note, that there are APIs that return String type hash and can verify it directly. This is done out of convenience and to present easy to understand API for all audiences. Usually the hash is not as critical as the raw password, so it might be ok to not be able to wipe it immediately. But usually you should prefer char[] or byte[] APIs.

Strict Verification

If you want the hash verification to only verify for a specific version you can use verifyStrict()

byte[] hash2y = BCrypt.with(BCrypt.Version.VERSION_2Y).hash(6, password.getBytes(StandardCharsets.UTF_8));
BCrypt.Result resultStrict = BCrypt.verifyer(BCrypt.Version.VERSION_2A).verifyStrict(password.getBytes(StandardCharsets.UTF_8), hash2y);
// resultStrict.verified == false

Handling for Overlong passwords

Due to the limitation in the Blowfish cipher, the maximum password length is 72 bytes (note that UTF-8 encoded, a character can be as much as 4 bytes). Per default, the hash() method will throw an exception if the provided password is too long.

The API supports passing a custom handling in that case, to mimic the behaviour of some popular implementations to just truncate the password.

BCrypt.with(LongPasswordStrategies.truncate(Version.VERSION_2A)).hash(6, pw);
BCrypt.with(LongPasswordStrategies.hashSha512(Version.VERSION_2A)).hash(6, pw); //allows to honour all pw bytes

Don't forget to use the same strategy when verifying:

BCrypt.verifyer(LongPasswordStrategies.truncate(Version.VERSION_2A)).verify(pw, hash);

The password will only be transformed if it is longer than 72 bytes. It is important to note, however, that using any of these techniques will essentially create a custom flavor of Bcrypt, possibly not compatible with other implementations.

However, you can also disable this warning by using the LongPasswordStrategies.none strategy. It will pass the raw data to the internal cryptographic primitive (which in turn will ignore anything longer than 72 bytes). This is the standard behaviour of BCrypt.

Custom Salt or SecureRandom

The caller may provide their own salt (which must be exactly 16 bytes) with:

BCrypt.withDefaults().hash(6, salt16Bytes, password.getBytes(StandardCharsets.UTF_8));

or provide a custom instance of a cryptographically secure pseudorandom number generator (CPRNG) which is used for the internal secure creation of the salt if none is passed:

BCrypt.with(new SecureRandom()).hash(6, password.getBytes(StandardCharsets.UTF_8));

Retrieve and Verify the Raw Hash

Per default the result of hash() methods will return in the Modular Crypt Format (e.g. $2y$06$doGnefu9cbLkJTn8sef7U.dynHJFe5hS6xp7vLWb2Zu7e8cOuMVmS), but if you prefer encoding the hash yourself you can just use

BCrypt.HashData hashData = BCrypt.withDefaults().hashRaw(6, salt, password.getBytes(StandardCharsets.UTF_8));

there is even a verify method optimized for this use-case:

BCrypt.Result result = BCrypt.verifyer().verify(pw, hashData);

You could even use the default formatter later on:

byet[] hashMsg = Version.VERSION_2A.formatter.createHashMessage(hashData);

Command Line Interface (CLI) Tool

In addition to the Java library there is a companion command line interface (CLI) tool (found in the bcrypt-cli sub-module) which uses this bcrypt library. It features creating bcrypt password hashes with chosen cost factor and optionally passed salt value as well as verifying given hash against given password.

This command will create a bcrypt hash:

java -jar bcrypt-cli.jar 'mySecretPw' -b 12

This command will verify given bcrypt hash (returns != 0 if could not be verified):

java -jar bcrypt-cli.jar 'mySecretPw' -c '$2a$08$hgaLWQl7PdKIkx9iQyoLkeuIqizWtPErpyC7aDBasi2Pav97wwW9G'

The full API can be read in the doc by passing -h

-b,--bhash <cost> <[16-hex-byte-salt]>   Use this flag if you want to compute the bcrypt hash. Pass the
                                         logarithm cost factor (4-31) and optionally the used salt as hex
                                         encoded byte array (must be exactly 16 bytes/32 characters hex).
                                         Example: '--bhash 12 8e270d6129fd45f30a9b3fe44b4a8d9a'
-c,--check <bcrypt-hash>                 Use this flag if you want to verify a hash against a given
                                         password. Example: '--check
                                         $2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i'
-h,--help                                Prints help docs.
-v,--version                             Prints current version.

Download

The artifacts are deployed to Maven Central.

Maven

Add the dependency of the latest version to your pom.xml:

<dependency>
    <groupId>at.favre.lib</groupId>
    <artifactId>bcrypt</artifactId>
    <version>{latest-version}</version>
</dependency>

Gradle

Add to your build.gradle module dependencies:

implementation group: 'at.favre.lib', name: '
View on GitHub
GitHub Stars556
CategoryDevelopment
Updated7d ago
Forks50

Languages

Java

Security Score

100/100

Audited on Mar 20, 2026

No findings