Copyright | (c) Leo D 2023 |
---|---|
License | BSD-3-Clause |
Maintainer | leo@apotheca.io |
Stability | experimental |
Portability | POSIX |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
Generate and validate Bcrypt password hashes
Synopsis
- bcryptGenerate :: BcryptPassword -> RNG -> BcryptWorkFactor -> IO BcryptDigest
- bcryptIsValid :: BcryptPassword -> BcryptDigest -> IO Bool
- type BcryptWorkFactor = Int
- pattern BcryptFast :: BcryptWorkFactor
- pattern BcryptGood :: BcryptWorkFactor
- pattern BcryptStrong :: BcryptWorkFactor
- type BcryptPassword = ByteString
- type BcryptDigest = ByteString
Bcrypt
bcrypt
is a password-hashing algorithm designed to protect your passwords
against hackers using an expensive key setup phase. Instead of storing a user's
password in plaintext in the database, the server may instead generate a salted
bcrypt digest upon signup, and verify it upon login.
The bcrypt
implementation provided by botan
generates a random salt for you
automatically. A work factor of 12 or greater is recommended.
Usage
To generate a bcrypt digest:
import Botan.Low.RNG import Botan.Low.Bcrypt -- The user has sent us a username and password in order to sign up onUserSignup :: ByteString -> ByteString -> IO () onUserSignup username password = do rng <- rngInit "user" digest <- bcryptGenerate password rng 12 createAndStoreNewUser username digest
To validate a bcrypt digest:
import Botan.Low.RNG import Botan.Low.Bcrypt -- The user has sent us a username and password in order to log in onUserLogin :: ByteString -> ByteString -> IO Bool onUserLogin username password = do rng <- rngInit "user" digestMaybe <- getStoredUserDigest username case digestMaybe of Nothing -> return False Just digest -> bcryptIsValid password digest
Generate a bcrypt digest
:: BcryptPassword | password: The password |
-> RNG | rng: A random number generator |
-> BcryptWorkFactor | work_factor: How much work to do to slow down guessing attacks. A value of 12 to 16 is probably fine. |
-> IO BcryptDigest |
Create a password hash using Bcrypt
rng <- rngInit "user" digest <- bcryptGenerate password rng 12
Output is formatted bcrypt $2a$...
Validate a bcrypt digest
:: BcryptPassword | password: The password to check against |
-> BcryptDigest | hash: The stored hash to check against |
-> IO Bool |
Check a previously created password hash
valid <- bcryptIsValid password digest if valid ...
Returns True iff this password/hash combination is valid, False if the combination is not valid (but otherwise well formed), and otherwise throws an exception on error.
Work factor
type BcryptWorkFactor = Int Source #
A work factor to slow down guessing attacks.
pattern BcryptFast :: BcryptWorkFactor Source #
Should not cause noticable CPU usage
pattern BcryptGood :: BcryptWorkFactor Source #
May cause noticable CPU usage
pattern BcryptStrong :: BcryptWorkFactor Source #
May block for several seconds
type BcryptPassword = ByteString Source #
A bcrypt password.
type BcryptDigest = ByteString Source #
A bcrypt-hashed password digest.