Merge pull request #34 from tekul/master

BCrypt module doc updates
This commit is contained in:
Vincent Hanquez 2015-09-07 10:25:54 +01:00
commit 495788dded

View File

@ -1,24 +1,45 @@
-- | Password encoding and validation using bcrypt. -- | 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 <https://www.usenix.org/conference/1999-usenix-annual-technical-conference/future-adaptable-password-scheme> -- See <https://www.usenix.org/conference/1999-usenix-annual-technical-conference/future-adaptable-password-scheme>
-- for details of the original algorithm. -- for details of the original algorithm.
-- --
-- Hashes are strings of the form @$2a$10$MJJifxfaqQmbx1Mhsq3oq.YmMmfNhkyW4s/MS3K5rIMVfB7w0Q/OW@ which -- The functions @hashPassword@ and @validatePassword@ should be all that
-- encode a version number, an integer cost parameter and the concatenated salt and hash bytes (each -- most users need.
-- separately Base64 encoded. Incrementing the cost parameter approximately doubles the time taken
-- to calculate the hash.
-- --
-- The different version numbers have evolved because of bugs in the standard C implementations. -- Hashes are strings of the form
-- The most up to date version is @2b@ and this implementation the @2b@ version prefix, but will also -- @$2a$10$MJJifxfaqQmbx1Mhsq3oq.YmMmfNhkyW4s/MS3K5rIMVfB7w0Q/OW@ which
-- attempt to validate against hashes with versions @2a@ and @2y@. Version @2@ or @2x@ will be rejected. -- encode a version number, an integer cost parameter and the concatenated
-- No attempt is made to differentiate between the different versions when validating a password, but -- salt and hash bytes (each separately Base64 encoded. Incrementing the
-- in practice this shouldn't cause any problems if passwords are UTF-8 encoded (which they should be). -- 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 -- The different version numbers have evolved because of bugs in the standard
-- enough. High values may be prohibitively slow depending on your hardware. Choose the highest value you -- C implementations. The most up to date version is @2b@ and this
-- can without having an unacceptable impact on your users. The cost parameter can also varied depending on -- implementation the @2b@ version prefix, but will also attempt to validate
-- the account, since it is unique to an individual hash. -- 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 module Crypto.KDF.BCrypt
( hashPassword ( hashPassword
@ -39,6 +60,8 @@ import Data.Char
data BCryptHash = BCH Char Int Bytes Bytes data BCryptHash = BCH Char Int Bytes Bytes
-- | Create a bcrypt hash for a password with a provided cost value. -- | 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. -- Each increment of the cost approximately doubles the time taken.
-- The 16 bytes of random salt will be generated internally. -- 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 :: (ByteArray ba) => ba -> ba
b64 = convertToBase Base64OpenBSD 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 -- Returns @False@ if the password doesn't match the hash, or if the hash is
-- invalid or an unsupported version. -- invalid or an unsupported version.