{"id":13552872,"url":"https://github.com/patrickfav/bcrypt","last_synced_at":"2025-05-14T01:10:18.011Z","repository":{"id":37735479,"uuid":"139898859","full_name":"patrickfav/bcrypt","owner":"patrickfav","description":"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.","archived":false,"fork":false,"pushed_at":"2025-03-30T08:03:45.000Z","size":2405,"stargazers_count":530,"open_issues_count":8,"forks_count":51,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-04-13T20:17:34.777Z","etag":null,"topics":["bcrypt","bcrypt-library","bycrypt-password","cli","crypto","hash","java","java-library","kdf","password-hash","security"],"latest_commit_sha":null,"homepage":"https://favr.dev/opensource/bcrypt","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/patrickfav.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-05T20:48:48.000Z","updated_at":"2025-04-11T14:15:57.000Z","dependencies_parsed_at":"2024-01-14T15:23:37.101Z","dependency_job_id":"e4da92e9-68d6-4680-b820-288a20ce5f20","html_url":"https://github.com/patrickfav/bcrypt","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickfav%2Fbcrypt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickfav%2Fbcrypt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickfav%2Fbcrypt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickfav%2Fbcrypt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patrickfav","download_url":"https://codeload.github.com/patrickfav/bcrypt/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248774961,"owners_count":21159534,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bcrypt","bcrypt-library","bycrypt-password","cli","crypto","hash","java","java-library","kdf","password-hash","security"],"created_at":"2024-08-01T12:02:12.302Z","updated_at":"2025-04-13T20:17:41.017Z","avatar_url":"https://github.com/patrickfav.png","language":"Java","readme":"# Bcrypt Java Library and CLI Tool\n\nThis is an implementation of the OpenBSD Blowfish password hashing algorithm, as described in \"[A Future-Adaptable Password Scheme](http://www.openbsd.org/papers/bcrypt-paper.ps)\" by Niels Provos and David Mazieres. It's core is based on [jBcrypt](https://github.com/djmdjm/jBCrypt), but  heavily refactored, modernized and with a lot of updates and enhancements. It supports all common [versions](https://en.wikipedia.org/wiki/Bcrypt#Versioning_history), has a security sensitive API and is fully tested against a range of test vectors and reference implementations.\n\n[![Maven Central](https://img.shields.io/maven-central/v/at.favre.lib/bcrypt)](https://mvnrepository.com/artifact/at.favre.lib/bcrypt)\n[![Github Actions](https://github.com/patrickfav/bcrypt/actions/workflows/build_deploy.yml/badge.svg)](https://github.com/patrickfav/bcrypt/actions)\n[![libs.tech recommends](https://libs.tech/project/139898859/badge.svg)](https://libs.tech/project/139898859/bcrypt)\n[![Javadocs](https://www.javadoc.io/badge/at.favre.lib/bcrypt.svg)](https://www.javadoc.io/doc/at.favre.lib/bcrypt)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=patrickfav_bcrypt\u0026metric=coverage)](https://sonarcloud.io/summary/new_code?id=patrickfav_bcrypt)\n[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=patrickfav_bcrypt\u0026metric=security_rating)](https://sonarcloud.io/summary/new_code?id=patrickfav_bcrypt)\n[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=patrickfav_bcrypt\u0026metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=patrickfav_bcrypt)\n\nThe code is compiled with target [Java 7](https://en.wikipedia.org/wiki/Java_version_history#Java_SE_7) to be compatible with most [_Android_](https://www.android.com/) versions as well as normal Java applications.\n\n## Quickstart\n\nThis library is published to Maven Central\n\nAdd the dependency of the [latest version](https://github.com/patrickfav/bcrypt/releases/latest) to your `pom.xml`:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eat.favre.lib\u003c/groupId\u003e\n    \u003cartifactId\u003ebcrypt\u003c/artifactId\u003e\n    \u003cversion\u003e{latest-version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nOr if you are using Gradle:\n\n```groovy\nimplementation(\"at.favre.lib:bcrypt:{latest-version}\")\n```\n\nA simple example:\n\n```java\nString password = \"1234\";\nString bcryptHashString = BCrypt.withDefaults().hashToString(12, password.toCharArray());\n// $2a$12$US00g/uMhoSBm.HiuieBjeMtoN69SN.GE25fCpldebzkryUyopws6\n    ...\nBCrypt.Result result = BCrypt.verifyer().verify(password.toCharArray(), bcryptHashString);\n// result.verified == true\n```\n\n## API Description for the Java Library\n\nThe following APIs are for advanced use-cases and require the developer to be familiar with the material. If you are not\nsure, just stick to the quick start example.\n\n### Bcrypt Versions\nThis implementation supports the various versions, which basically only differ through their identifier:\n\n```java\nchar[] bcryptChars = BCrypt.with(BCrypt.Version.VERSION_2Y).hashToChar(6, password.toCharArray());\n// $2y$06$doGnefu9cbLkJTn8sef7U.dynHJFe5hS6xp7vLWb2Zu7e8cOuMVmS\n\nchar[] bcryptChars = BCrypt.with(BCrypt.Version.VERSION_2B).hashToChar(6, password.toCharArray());\n// $2b$06$GskjDDM9oejRN8pxNhiSZuIw/cnjbsNb8IfWGd3TFQXtRfKTN95r.\n```\n\nFor example the [PHP implementation of bcrypt](http://php.net/manual/en/function.password-hash.php) will return hashes with version `$2y$`.\nBy using `BCrypt.withDefaults()` it will default to version `$2a$`. The older `$2$` version is not supported.\nFor advanced use cases you may add your own version by providing a version identifier and a custom message formatter \nas well as parser.\n\n```java\nVersion customVersion2f = new Version(new byte[]{0x32, 0x66} /* 2f */, true, true, myCustomFormatter, myCustomParser);\n```\n\n### byte[] vs char[] API\n\nYou can use either `char[]` or `byte[]` as input or output parameter. The reason `String` is usually omitted in security\nrelevant APIs is, that a primitive array can usually be overwritten, as to discard it immediately after use. It is however \nnot possible to wipe the content of the immutable `String`. The encoding always defaults to `UTF-8`.\n\n```java\nbyte[] bcryptHashBytes = BCrypt.withDefaults().hash(6, password.getBytes(StandardCharsets.UTF_8));\n    ...\nBCrypt.Result result = BCrypt.verifyer().verify(password.getBytes(StandardCharsets.UTF_8), bcryptHashBytes);\n```\n\nand\n\n```java\nchar[] bcryptChars = BCrypt.withDefaults().hashToChar(12, password.toCharArray());\n    ...\nBCrypt.Result result = BCrypt.verifyer().verify(password.toCharArray(), bcryptChars);\n```\n\nNote, that there are APIs that return `String` type hash and can verify it directly. This is done\nout of convenience and to present easy to understand API for all audiences. Usually the hash is \nnot as critical as the raw password, so it might be ok to not be able to wipe it immediately. But \nusually you should prefer `char[]` or `byte[]` APIs.\n\n### Strict Verification\n\nIf you want the hash verification to only verify for a specific version you can use `verifyStrict()`\n\n```java\nbyte[] hash2y = BCrypt.with(BCrypt.Version.VERSION_2Y).hash(6, password.getBytes(StandardCharsets.UTF_8));\nBCrypt.Result resultStrict = BCrypt.verifyer(BCrypt.Version.VERSION_2A).verifyStrict(password.getBytes(StandardCharsets.UTF_8), hash2y);\n// resultStrict.verified == false\n```\n\n### Handling for Overlong passwords\n\nDue to the limitation in the Blowfish cipher, the maximum password length is 72 bytes (note that UTF-8 encoded, a \ncharacter can be as much as 4 bytes). Per \ndefault, the `hash()` method will throw an exception if the provided password is too long. \n\nThe API supports passing a custom handling in that case, to mimic the behaviour of some popular implementations to just\ntruncate the password.\n\n```java\nBCrypt.with(LongPasswordStrategies.truncate(Version.VERSION_2A)).hash(6, pw);\nBCrypt.with(LongPasswordStrategies.hashSha512(Version.VERSION_2A)).hash(6, pw); //allows to honour all pw bytes\n```\n\nDon't forget to use the same strategy when verifying:\n\n```java\nBCrypt.verifyer(LongPasswordStrategies.truncate(Version.VERSION_2A)).verify(pw, hash);\n```\n\nThe password will only be transformed if it is longer than 72 bytes. *It is important to note, however, that using any\nof these techniques will essentially create a custom flavor of Bcrypt, possibly not compatible with other implementations.*\n\nHowever, 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.\n\n### Custom Salt or SecureRandom\n \nThe caller may provide their own salt (which must be exactly 16 bytes) with:\n \n```java\nBCrypt.withDefaults().hash(6, salt16Bytes, password.getBytes(StandardCharsets.UTF_8));\n```\n\nor provide a custom instance of a cryptographically secure pseudorandom number generator ([CPRNG](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator)) \nwhich is used for the internal secure creation of the salt if none is passed:\n\n```java\nBCrypt.with(new SecureRandom()).hash(6, password.getBytes(StandardCharsets.UTF_8));\n```\n\n### Retrieve and Verify the Raw Hash\n\nPer default the result of `hash()` methods will return in the [Modular Crypt Format](https://passlib.readthedocs.io/en/stable/modular_crypt_format.html)\n(e.g. `$2y$06$doGnefu9cbLkJTn8sef7U.dynHJFe5hS6xp7vLWb2Zu7e8cOuMVmS`), but if you prefer encoding the hash yourself you can just use\n\n```java\nBCrypt.HashData hashData = BCrypt.withDefaults().hashRaw(6, salt, password.getBytes(StandardCharsets.UTF_8));\n```\n\nthere is even a verify method optimized for this use-case:\n\n```java\nBCrypt.Result result = BCrypt.verifyer().verify(pw, hashData);\n```\n\nYou could even use the default formatter later on:\n\n```java\nbyet[] hashMsg = Version.VERSION_2A.formatter.createHashMessage(hashData);\n```\n\n## Command Line Interface (CLI) Tool\n\nIn addition to the Java library there is a companion command line interface (CLI) tool (found in the `bcrypt-cli` \nsub-module) which uses this bcrypt library. It features creating bcrypt password hashes with chosen cost factor and \noptionally passed salt value as well as verifying given hash against given password.\n\nThis command will create a bcrypt hash:\n\n    java -jar bcrypt-cli.jar 'mySecretPw' -b 12\n\nThis command will verify given bcrypt hash (returns `!= 0` if could not be verified):\n\n    java -jar bcrypt-cli.jar 'mySecretPw' -c '$2a$08$hgaLWQl7PdKIkx9iQyoLkeuIqizWtPErpyC7aDBasi2Pav97wwW9G'\n\nThe full API can be read in the doc by passing `-h`\n\n    -b,--bhash \u003ccost\u003e \u003c[16-hex-byte-salt]\u003e   Use this flag if you want to compute the bcrypt hash. Pass the\n                                             logarithm cost factor (4-31) and optionally the used salt as hex\n                                             encoded byte array (must be exactly 16 bytes/32 characters hex).\n                                             Example: '--bhash 12 8e270d6129fd45f30a9b3fe44b4a8d9a'\n    -c,--check \u003cbcrypt-hash\u003e                 Use this flag if you want to verify a hash against a given\n                                             password. Example: '--check\n                                             $2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i'\n    -h,--help                                Prints help docs.\n    -v,--version                             Prints current version.\n\n## Download\n\nThe artifacts are deployed to [Maven Central](https://search.maven.org/).\n\n### Maven\n\nAdd the dependency of the [latest version](https://github.com/patrickfav/bcrypt/releases) to your `pom.xml`:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eat.favre.lib\u003c/groupId\u003e\n    \u003cartifactId\u003ebcrypt\u003c/artifactId\u003e\n    \u003cversion\u003e{latest-version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle\n\nAdd to your `build.gradle` module dependencies:\n\n    implementation group: 'at.favre.lib', name: 'bcrypt', version: '{latest-version}'\n\n### Local Jar Library\n\n[Grab jar from latest release.](https://github.com/patrickfav/bcrypt/releases/latest)\n\n### OSGi\n\nThe library should be prepared to be used with the OSGi framework with the help of the [bundle plugin](http://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html).\n\n### CLI Tool\n\nGet the binary from the [release page](https://github.com/patrickfav/bcrypt/releases/latest) or build it yourself by with mvn (see below). The `jar`\nwill be in the `bcrypt-cli/target` folder.\n\n## Description\n\n### Security Analysis\n\nI'll quote security expert [Thomas Pornin](http://www.bolet.org/~pornin/) on this (an excerpt [from this post](https://security.stackexchange.com/a/6415/60108)):\n\n**tl;dr bcrypt is better than PBKDF2 because PBKDF2 can be better accelerated with GPUs. As such, PBKDF2 is easier to brute \nforce offline with consumer hardware. [srcypt tried to address bcrypt's shortcommings, but didn't succeed all the way.](https://security.stackexchange.com/a/26253/60108) \n[Argon2 is too new to tell.](https://security.stackexchange.com/a/119784/60108)**\n\n\u003e Bcrypt has the best kind of repute that can be achieved for a cryptographic algorithm: it has been around for quite some time, used quite widely, \"attracted attention\", and yet remains unbroken to date.\n\u003e\n\u003e\n\u003e #### Why bcrypt is somewhat better than PBKDF2\n\u003e\n\u003e If you look at the situation in details, you can actually see some points where bcrypt is better than, say, PBKDF2. Bcrypt is a password hashing function which aims at being slow. To be precise, we want the password hashing function to be as slow as possible for the attacker while not being intolerably slow for the honest systems. (...)\n\u003e What we want to avoid is that an attacker might use some non-PC hardware which would allow him to suffer less than us from the extra work implied by bcrypt or PBKDF2. In particular, an industrious attacker may want to use a GPU or a FPGA. SHA-256, for instance, can be very efficiently implemented on a GPU, since it uses only 32-bit logic and arithmetic operations that GPU are very good at. (...)\n\u003e Bcrypt happens to heavily rely on accesses to a table which is constantly altered throughout the algorithm execution. This is very fast on a PC, much less so on a GPU, where memory is shared and all cores compete for control of the internal memory bus. Thus, the boost that an attacker can get from using GPU is quite reduced, compared to what the attacker gets with PBKDF2 or similar designs.\n\u003e \n\u003e\n\u003e #### Why bcrypt is not optimally secure\n\u003e\n\u003e Bcrypt needs only 4 kB of fast RAM. While bcrypt does a decent job at making life difficult for a GPU-enhanced attacker, it does little against a FPGA-wielding attacker.\n\u003e\n\u003e\n\u003e #### What NIST recommends\n\u003e\n\u003e NIST has issued Special Publication SP 800-132 on the subject of storing hashed passwords. Basically they recommend PBKDF2. This does not mean that they deem bcrypt insecure; they say nothing at all about bcrypt. It just means that NIST deems PBKDF2 \"secure enough\" (and it certainly is much better than a simple hash !). Also, NIST is an administrative organization, so they are bound to just love anything which builds on already \"Approved\" algorithms like SHA-256. On the other hand, bcrypt comes from Blowfish which has never received any kind of NIST blessing (or curse).\n\n#### What Cost Factor should I use?\n\nAgain, quote from Thomas Pornin [from this post](https://security.stackexchange.com/a/31846/60108):\n\n\u003e As much as possible! This salted-and-slow hashing is an arms race between the attacker and the defender. You use many iterations to make the hashing of a password harder for everybody. To improve security, you should set that number as high as you can tolerate on your server, given the tasks that your server must otherwise fulfill. Higher is better.\n\nSo find your tolerable slowest performance (for some this is 3 sec, for some 250 ms, for some 1 minute) and try it out on an average lower end device your user-base would use (if the client has to calculate the hash) and/or benchmark your server.\n\nNote, that it is unfortunately [NOT possible to increase the cost-factor](https://security.stackexchange.com/a/23308/60108) \nof a calculated bcrypt hash without knowing the original password. A possible solution is to persist hashes with multiple work factors for\ndifferent use cases/migration.\n\n### Performance\n\nCompared to two other implementations in Java they all share similar performance characteristics. Using the simple micro\n benchmark in this repo (see `BcryptMicroBenchmark`), I got the following results with a Intel Core [i7-7700K](https://ark.intel.com/products/97129/Intel-Core-i7-7700K-Processor-8M-Cache-up-to-4_50-GHz), Win 10, \n Java 8 (172):\n\n|              | cost 6   | cost   8  | cost 10  | cost 12   | cost 14   |\n|--------------|----------|-----------|----------|-----------|-----------|\n| favreBcrypt  |  3.38 ms |  13.54 ms | 53.91 ms | 216.01 ms | 873.93 ms |\n| jBcrypt      |  3.43 ms |  13.75 ms | 54.76 ms | 218.62 ms | 883.55 ms |\n| BouncyCastle |  3.14 ms |  12.5 ms  | 49.8 ms  | 199.09 ms | 799.71 ms |\n\ncompare that with a 2017 flag ship Android phone Samsung Galaxy S8+ ([SM-G955F](https://www.gsmarena.com/samsung_galaxy_s8+-8523.php)) with Android 8:\n\n|              | cost 6   | cost   8  | cost 10   | cost 12   | cost 14   |\n|--------------|----------|-----------|-----------|-----------|-----------|\n| favreBcrypt  |  8.13 ms |  29.05 ms | 110.62 ms | 438.45 ms | 1768.44 ms|\n| jBcrypt      |  7.91 ms |  30.91 ms | 116.45 ms | 462.93 ms | 1855.36 ms|\n| BouncyCastle |  10.41 ms|  38.03 ms | 149.09 ms | 595.19 ms | 2383.72 ms|\n\nMore benchmarks can be found in the [wiki](https://github.com/patrickfav/bcrypt/wiki/Benchmark).\n\nSo it makes sense that this implementation and jBcrypt's has the same performance as it is the same core\nimplementation. Bouncy Castle is _slightly_ faster (on the JVM, not on Android interestingly), but keep in mind that they do a little less work (only generating the hash, not the whole out message).\n\nCompare this to other benchmarks, [like this one in node.js](https://github.com/dcodeIO/bcrypt.js/wiki/Benchmark) where a bcrypt hash with cost factor 12 is between 300-400ms.\n\n**Disclaimer:** Micro benchmarks are [usually a really bad way to measure performance](https://mrale.ph/blog/2012/12/15/microbenchmarks-fairy-tale.html). \nThese numbers are only informal tests and should not be used to derive any security relevant decisions.\n\n#### JMH Benchmark\n\nAdditionally there is JMH benchmark module, which is probably better than my home-brew micro benchmark. Build it with \nmaven `./mvnw clean install` (you may want to disable jar signing with `\u003cproject.skipJarSign\u003e` property) and execute\nit with `java -jar modules/benchmark-jmh/target/benchmark-jmh-x.y.z-full.jar`.\n\n### Test Vectors and Reference Implementations\n\nThis implementation is tested against the bcrypt implementation jBcrypt and Bouncy Castle. It includes test vectors\nfound in the test cases of bcrypt and [various](https://stackoverflow.com/a/12761326/774398) [places](http://openwall.info/wiki/john/sample-hashes) [on](http://cvsweb.openwall.com/cgi/cvsweb.cgi/Owl/packages/glibc/crypt_blowfish/wrapper.c?rev=HEAD) [the web](https://github.com/BcryptNet/bcrypt.net/blob/main/src/BCrypt.Net.UnitTests/BCryptTests.cs). Additionally I [created a reference test suite](https://github.com/patrickfav/bcrypt/wiki/Published-Test-Vectors) for regression tests and to check compatibility with\nother libraries.\n\n### The Modular Crypt Format for bcrypt\n\nSince bcrypt evolved from OpenBSD most implementations output the hash in the modular crypt format (MCF). In contrast to e.g. normal `sha` hash\nit includes the used hash function, cost factor, salt and hash itself. This makes it specifically convenient for password storage use. Formally \nthe [format](http://passlib.readthedocs.io/en/stable/modular_crypt_format.html) is:\n\n\u003e (...) a standard for encoding password hash strings, which requires hashes have the format `${identifier}${content}`; where `{identifier}` \n\u003e is an short alphanumeric string uniquely identifying a particular scheme, and `{content}` is the contents of the scheme, using only the \n\u003e characters in the regexp range `[a-zA-Z0-9./]`.\n\nAnalyzing the bcrypt format in detail we get:\n\n     ${identifier}${cost-factor}${16-bytes-salt-radix64}{23-bytes-hash-radix64}\n     \nWith bcrypt the version identifier was `$2$`, but unfortunately early implementations [did not define how to handle non-ASCII characters](http://undeadly.org/cgi?action=article\u0026sid=20140224132743),\nso to tag the old hashes, a new minor version was introduced which was not compatible with the earlier one: `$2a$`. \nThis is the default version used by most implementations. There are other minor versions which are only used to tag various non-backwards \ncompatible bugs in different implementations (namely `$2x$` and `$2y$` used by `crypt_blowfish` (PHP) and `$2b$` by OpenBSD). These are usually \nirrelevant for implementations that did not have these bugs, so there is no advantage in setting the version to e.g. `$2y$` apart from making \nit compatible with different systems. The actual format is the same as `$2a$`.\n\nThe cost factor is the logarithmic work factor value as defined (4-30) printed as normal ASCII characters `[0-9]`. After that the 16 byte salt \nencoded with a base64 dialect follows (22 characters) as well as the actual bcrypt hash (23 bytes / 31 characters encoded with the base64 dialect).\n\nHere is a full example:\n\n    $2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V.\n\nHere `$2a$` is the version, the cost factor is `8`, the salt is `cfcvVd2aQ8CMvoMpP2EBfe` and the bcrypt hash is `odLEkkFJ9umNEfPD18.hUF62qqlC/V.`.\n\nThe used encoding is similar to the RFC * base64 encoding schema, but [with different mappings](https://en.wikipedia.org/wiki/Base64#Radix-64_applications_not_compatible_with_Base64)\n (`./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz` vs. `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`) \n only used by OpenBSD. In the code base this encoding is usually referenced as \"Radix64\" (see `Radix64Encoder`). The usual padding with `=` is\n omitted.\n\n### Enhancements over jBcrypt\n\nThe core of this implementation is based on the popular jBcrypt. Many things around if have been heavily refactored and various new\nfeatures and APIs have been added:\n\n* Optimized and fixed implementation\n* Support of most [version](https://en.wikipedia.org/wiki/Bcrypt#Versioning_history) variations (`$2a$`, `$2b$`, `$2x$`, `$2y$`) with support of custom versions\n* Customizable handling for passwords over 72 bytes\n* Only uses byte and char arrays which can be wiped after use\n* Faster Radix64 implementation\n* Allow a cost factor of 31 (jBcrypt only allows up to 30)\n* Easily get the raw hash\n* Provide your own salt or `SecureRandom` for salt generation\n* Clearer and easier API\n* Signed Jar and signed commits\n* More tests (and probably higher coverage)\n\n## Security Relevant Information\n\n### OWASP Dependency Check\n\nThis project uses the [OWASP Dependency-Check](https://www.owasp.org/index.php/OWASP_Dependency_Check) which is a utility that identifies project dependencies and checks if there are any known, publicly disclosed, vulnerabilities against a [NIST database](https://nvd.nist.gov/vuln/data-feeds).\nThe build will fail if any issue is found.\n\n### Digital Signatures\n\n#### Signed Jar\n\nThe provided JARs in the Github release page are signed with my private key:\n\n    CN=Patrick Favre-Bulle, OU=Private, O=PF Github Open Source, L=Vienna, ST=Vienna, C=AT\n    Validity: Thu Sep 07 16:40:57 SGT 2017 to: Fri Feb 10 16:40:57 SGT 2034\n    SHA1: 06:DE:F2:C5:F7:BC:0C:11:ED:35:E2:0F:B1:9F:78:99:0F:BE:43:C4\n    SHA256: 2B:65:33:B0:1C:0D:2A:69:4E:2D:53:8F:29:D5:6C:D6:87:AF:06:42:1F:1A:EE:B3:3C:E0:6D:0B:65:A1:AA:88\n\nUse the jarsigner tool (found in your `$JAVA_HOME/bin` folder) folder to verify.\n\n#### Signed Commits\n\nAll tags and commits by me are signed with git with my private key:\n\n    GPG key ID: 4FDF85343912A3AB\n    Fingerprint: 2FB392FB05158589B767960C4FDF85343912A3AB\n\n## Build\n\n### Jar Sign\n\nIf you want to jar sign you need to provide a file `keystore.jks` in the\nroot folder with the correct credentials set in environment variables (\n`OPENSOURCE_PROJECTS_KS_PW` and `OPENSOURCE_PROJECTS_KEY_PW`); alias is\nset as `pfopensource`.\n\nIf you want to skip jar signing just change the skip configuration in the\n`pom.xml` jar sign plugin to true:\n\n    \u003cproject.skipJarSign\u003etrue\u003c/project.skipJarSign\u003e\n\n### Build with Maven\n\nUse the Maven wrapper to create a jar including all dependencies\n\n    ./mvnw clean install\n\n### Checkstyle Config File\n\nThis project uses my [`common-parent`](https://github.com/patrickfav/mvn-common-parent) which centralized a lot of\nthe plugin versions aswell as providing the checkstyle config rules. Specifically they are maintained in [`checkstyle-config`](https://github.com/patrickfav/checkstyle-config). Locally the files will be copied after you `mvnw install` into your `target` folder and is called\n`target/checkstyle-checker.xml`. So if you use a plugin for your IDE, use this file as your local configuration.\n\n## Tech Stack\n\n* Java 7 Source, JDK 11 required to build (not yet JDK17 compatible)\n* Maven 3\n\n## Libraries \u0026 Credits\n\n* [jBcrypt](https://github.com/djmdjm/jBCrypt) (derived the \"Blowfish Expensive key setup\") (under BSD licence)\n* Radix64 implementation derived from [Square's Okio Base64](https://github.com/square/okio) (under Apache v2)\n* [Bytes](https://github.com/patrickfav/bytes-java) (byte array utility library) (under Apache v2)\n\n\n### BCrypt Implementations in Java\n\n* [jBcrypt](https://github.com/djmdjm/jBCrypt) - the below implementations are based on jBcrypt\n  * [Spring Bcrypt](https://docs.spring.io/spring-security/site/docs/4.2.5.RELEASE/apidocs/org/springframework/security/crypto/bcrypt/BCrypt.html)\n  * [Apache Ldap](https://directory.apache.org/api/gen-docs/latest/apidocs/org/apache/directory/api/ldap/model/password/BCrypt.html)\n  * [Tomcat Bcrypt](https://github.com/andreacomo/tomcat-bcrypt)\n* [Bouncy Castle](https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/crypto/generators/BCrypt.java)\n\n## Further Reading\n\n* [The Bcrypt Protocol… is kind of a mess](https://hackernoon.com/the-bcrypt-protocol-is-kind-of-a-mess-4aace5eb31bd)\n\n## Related Libraries\n\n* [Single Step KDF [NIST SP 800-56C] (Java)](https://github.com/patrickfav/singlestep-kdf)\n* [HKDF [RFC5869] Two-Step KDF (Java)](https://github.com/patrickfav/hkdf)\n\n# License\n\nCopyright 2018 Patrick Favre-Bulle\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","funding_links":[],"categories":["Java","安全","cli"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatrickfav%2Fbcrypt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpatrickfav%2Fbcrypt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatrickfav%2Fbcrypt/lists"}