From 6d33b6624569e639129e6cd753b5b4c70a8dbff0 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Tue, 1 Sep 2015 14:14:04 +0100 Subject: [PATCH] BCrypt module doc updates - Add doctest style example usage - List most relevant functions - Reformat comments - Minor corrections and additions --- Crypto/KDF/BCrypt.hs | 51 ++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/Crypto/KDF/BCrypt.hs b/Crypto/KDF/BCrypt.hs index 700f41e..0356367 100644 --- a/Crypto/KDF/BCrypt.hs +++ b/Crypto/KDF/BCrypt.hs @@ -1,24 +1,45 @@ -- | Password encoding and validation using bcrypt. -- +-- Example usasge: +-- +-- >>> import Crypto.KDF.BCrypt (hashPassword, validatePassword) +-- >>> import qualified Data.ByteString.Char8 as B +-- >>> +-- >>> let bcryptHash = B.pack "$2a$10$MJJifxfaqQmbx1Mhsq3oq.YmMmfNhkyW4s/MS3K5rIMVfB7w0Q/OW" +-- >>> let password = B.pack "password" +-- >>> validatePassword password bcryptHash +-- >>> True +-- >>> let otherPassword = B.pack "otherpassword" +-- >>> otherHash <- hashPassword 12 otherPasssword :: IO B.ByteString +-- >>> validatePassword otherPassword otherHash +-- >>> True +-- -- See -- for details of the original algorithm. -- --- Hashes are strings of the form @$2a$10$MJJifxfaqQmbx1Mhsq3oq.YmMmfNhkyW4s/MS3K5rIMVfB7w0Q/OW@ 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 functions @hashPassword@ and @validatePassword@ should be all that +-- most users need. -- --- The different version numbers have evolved because of bugs in the standard C implementations. --- The most up to date version is @2b@ and this implementation 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). +-- Hashes are strings of the form +-- @$2a$10$MJJifxfaqQmbx1Mhsq3oq.YmMmfNhkyW4s/MS3K5rIMVfB7w0Q/OW@ 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 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 varied depending on --- the account, since it is unique to an individual hash. +-- The different version numbers have evolved because of bugs in the standard +-- C implementations. The most up to date version is @2b@ and this +-- implementation 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). +-- +-- 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. module Crypto.KDF.BCrypt ( hashPassword @@ -39,6 +60,8 @@ import Data.Char data BCryptHash = BCH Char Int Bytes Bytes -- | 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. @@ -80,7 +103,7 @@ bcrypt cost salt password = B.concat [header, B.snoc costBytes dollar, b64 salt, b64 :: (ByteArray ba) => ba -> ba b64 = convertToBase Base64OpenBSD --- | Check a password against a bcrypt hash +-- | 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.