| Copyright | (c) Leo D 2023 |
|---|---|
| License | BSD-3-Clause |
| Maintainer | leo@apotheca.io |
| Stability | experimental |
| Portability | POSIX |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
Botan.Low.Bcrypt
Description
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 digestTo 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 digestGenerate a bcrypt digest
Arguments
| :: 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
Arguments
| :: 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.