HORIZON HASKELLDocslts/ghc-10.0.xaa25b892026-10-10Search names, modules, packages, or :: a typeCtrl K

GHC 10.0.0.20260917 · lts/ghc-10.0.x · aa25b89 · 2026-10-10

Modulecrypton-2.1.7Haskell2010

Crypto.KDF.BCrypt

Password encoding and validation using bcrypt.

Example usage:

Example11 expressions
import Crypto.KDF.BCrypt (hashPassword, validatePassword)import qualified Data.ByteString.Char8 as Blet bcryptHash = B.pack "$2a$10$MJJifxfaqQmbx1Mhsq3oq.YmMmfNhkyW4s/MS3K5rIMVfB7w0Q/OW"let password = B.pack "password"validatePassword password bcryptHashTruelet otherPassword = B.pack "otherpassword"otherHash <- hashPassword 12 otherPassword :: IO B.ByteStringvalidatePassword otherPassword otherHashTrue

See https://www.usenix.org/conference/1999-usenix-annual-technical-conference/future-adaptable-password-scheme for details of the original algorithm.

The functions hashPassword and validatePassword should be all that most users need.

Hashes are strings of the form $2a$10$MJJifxfaqQmbx1Mhsq3oq.YmMmfNhkyW4sMS3K5rIMVfB7w0QOW which encode a version number, an integer cost parameter and the concatenated salt and hash bytes (each separately Base64 encoded. Incrementing the cost parameter approximately doubles the time taken to calculate the hash.

The different version numbers evolved to account for bugs in the standard C implementations. They don't represent different versions of the algorithm itself and in most cases should produce identical results. The most up to date version is 2b and this implementation uses the 2b version prefix, but will also attempt to validate against hashes with versions 2a and 2y. Version 2 or 2x will be rejected. No attempt is made to differentiate between the different versions when validating a password, but in practice this shouldn't cause any problems if passwords are UTF-8 encoded (which they should be) and less than 256 characters long.

Only the first 72 bytes of a password are used. The rest is silently ignored, so two passwords sharing a 72-byte prefix produce the same hash and validate against each other. That is what the original implementation does and is kept for compatibility, but it means a longer passphrase buys nothing past that point, and the limit is on bytes rather than characters -- a UTF-8 passphrase reaches it sooner than its length in characters suggests. Where passwords may be longer, hash them to a fixed size first, or use Crypto.KDF.Argon2 or Crypto.KDF.Scrypt, which have no such limit.

The cost parameter can be between 4 and 31 inclusive, but anything less than 10 is probably not strong enough. High values may be prohibitively slow depending on your hardware. Choose the highest value you can without having an unacceptable impact on your users. The cost parameter can also be varied depending on the account, since it is unique to an individual hash.

  • 6 values
  • Packagecrypton-2.1.7
  • Exports6
  • LanguageHaskell2010
  • LicenceBSD-3-Clause AND MIT AND ISC
  • SourceBCrypt.hs
valuehashPassword
  1. :: (MonadRandom m, ByteArray password, ByteArray hash)
  2. => Int

    The cost parameter. Must be between 4 and 31 inclusive; anything else is refused.

  3. -> password

    The password. Should be the UTF-8 encoded bytes of the password text. Only the first 72 bytes are used; see the module documentation.

  4. -> m hash

    The bcrypt hash in standard format.

#

Create a bcrypt hash for a password with a provided cost value. Typically used to create a hash when a new user account is registered or when a user changes their password.

Each increment of the cost approximately doubles the time taken. The 16 bytes of random salt will be generated internally.

A cost outside 4 to 31 raises CryptoError_ParameterInvalid; tryHashPassword reports it instead.

valuetryHashPassword
  1. :: (MonadRandom m, ByteArray password, ByteArray hash)
  2. => Int

    The cost parameter. Must be between 4 and 31 inclusive; anything else is reported.

  3. -> password

    The password. Should be the UTF-8 encoded bytes of the password text. Only the first 72 bytes are used; see the module documentation.

  4. -> m (CryptoFailable hash)

    The bcrypt hash in standard format.

#

Create a bcrypt hash for a password with a provided cost value, reporting a cost the implementation refuses rather than raising.

The salt is generated internally and is always the right length, so the cost is the only thing here that can be wrong.

valuevalidatePassword
  1. :: (ByteArray password, ByteArray hash)
  2. => password
  3. -> hash
  4. -> Bool
#

Check a password against a stored bcrypt hash when authenticating a user.

Returns False if the password doesn't match the hash, or if the hash is invalid or an unsupported version.

Only the first 72 bytes of the password are compared; see the module documentation.

valuevalidatePasswordEither
  1. :: (ByteArray password, ByteArray hash)
  2. => password
  3. -> hash
  4. -> Either String Bool
#

Check a password against a bcrypt hash

As for validatePassword but will provide error information if the hash is invalid or an unsupported version. The same 72-byte limit applies.

valuebcrypt
  1. :: (ByteArray salt, ByteArray password, ByteArray output)
  2. => Int

    The cost parameter. Must be between 4 and 31 inclusive; anything else is refused.

  3. -> salt

    The salt. Must be 16 bytes in length or an error will be raised.

  4. -> password

    The password. Should be the UTF-8 encoded bytes of the password text. Only the first 72 bytes are used; see the module documentation.

  5. -> output

    The bcrypt hash in standard format.

#

Create a bcrypt hash for a password with a provided cost value and salt.

A cost outside 4 to 31, or a salt that is not 16 bytes long, raises CryptoError_ParameterInvalid; tryBcrypt reports the same conditions as CryptoFailed.

valuetryBcrypt
  1. :: (ByteArray salt, ByteArray password, ByteArray output)
  2. => Int

    The cost parameter. Must be between 4 and 31 inclusive; anything else is refused.

  3. -> salt

    The salt. Must be 16 bytes in length.

  4. -> password

    The password. Should be the UTF-8 encoded bytes of the password text. Only the first 72 bytes are used; see the module documentation.

  5. -> CryptoFailable output

    The bcrypt hash in standard format.

#

Create a bcrypt hash for a password with a provided cost value and salt, reporting a parameter the implementation refuses rather than raising.

bcrypt is defined for a cost of 4 to 31, and a cost outside that is reported rather than replaced by one inside it: a caller that asks for something this does not do should hear so, not receive a hash at a cost it did not choose.