Copyright | (c) Dennis Gosnell 2019 |
---|---|
License | BSD-style (see LICENSE file) |
Maintainer | cdep.illabout@gmail.com |
Stability | experimental |
Portability | POSIX |
Safe Haskell | None |
Language | Haskell2010 |
This module provides the same interface as Data.Password, but it also
provides additional typeclass instances for Pass
and PassHash
.
See the Data.Password module for more information.
Synopsis
- newtype Pass = Pass {}
- newtype PassHash = PassHash {
- unPassHash :: Text
- newtype Salt = Salt {}
- hashPass :: MonadIO m => Pass -> m PassHash
- hashPassWithSalt :: Pass -> Salt -> PassHash
- newSalt :: IO Salt
- checkPass :: Pass -> PassHash -> PassCheck
- data PassCheck
- unsafeShowPassword :: Pass -> String
- unsafeShowPasswordText :: Pass -> Text
Plaintext Password
A plain-text password.
This represents a plain-text password that has NOT been hashed.
You should be careful with Pass
. Make sure not to write it to logs or
store it in a database.
Instances
Read Pass | |
IsString Pass | |
Defined in Data.Password fromString :: String -> Pass # | |
FromJSON Pass Source # | This instance allows a
There is no instance for Similarly, there is no |
FromHttpApiData Pass Source # | This instance allows a
|
Defined in Data.Password.Instances parseUrlPiece :: Text -> Either Text Pass # parseHeader :: ByteString -> Either Text Pass # |
Hashed Password
A hashed password.
This represents a password that has been put through a hashing function. The hashed password can be stored in a database.
Instances
Eq PassHash | |
Ord PassHash | |
Defined in Data.Password | |
Read PassHash | |
Show PassHash | |
PersistFieldSql PassHash Source # | This instance allows a |
PersistField PassHash Source # | This instance allows a
In the example above, the long We don't provide an instance of |
Defined in Data.Password.Instances |
Functions for Hashing Plaintext Passwords
hashPass :: MonadIO m => Pass -> m PassHash #
Just like hashPassWithSalt
, but generate a new Salt
everytime with a
call to newSalt
.
>>>
hashPass (Pass "foobar")
PassHash {unPassHash = "14|8|1|...|..."}
hashPassWithSalt :: Pass -> Salt -> PassHash #
Hash a password with the given Salt
.
The resulting PassHash
has the parameters used to hash it, as well as the
Salt
appended to it, separated by |
.
The input Salt
and resulting PassHash
are both byte-64 encoded.
>>>
let salt = Salt "abcdefghijklmnopqrstuvwxyz012345"
>>>
hashPassWithSalt (Pass "foobar") salt
PassHash {unPassHash = "14|8|1|YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU=|nENDaqWBmPKapAqQ3//H0iBImweGjoTqn5SvBS8Mc9FPFbzq6w65maYPZaO+SPamVZRXQjARQ8Y+5rhuDhjIhw=="}
(Note that we use an explicit Salt
in the example above. This is so that the
example is reproducible, but in general you should use hashPass
. hashPass
generates a new Salt
everytime it is called.)
This function uses the hash function from the scrypt package: encryptPass
.
Functions for Checking Plaintext Passwords Against Hashed Passwords
checkPass :: Pass -> PassHash -> PassCheck #
Check a Pass
against a PassHash
.
Returns PassCheckSucc
on success.
>>>
let salt = Salt "abcdefghijklmnopqrstuvwxyz012345"
>>>
let pass = Pass "foobar"
>>>
let passHash = hashPassWithSalt pass salt
>>>
checkPass pass passHash
PassCheckSucc
Returns PassCheckFail
If an incorrect Pass
or PassHash
is used.
>>>
let badpass = Pass "incorrect-password"
>>>
checkPass badpass passHash
PassCheckFail
This should always fail if an incorrect password is given.
\(Blind badpass) -> let correctPassHash = hashPassWithSalt (Pass "foobar") salt in checkPass badpass correctPassHash == PassCheckFail
The result of a checking a password against a hashed version. This is
returned by checkPass
.
PassCheckSucc | The password check was successful. The plain-text password matches the hashed password. |
PassCheckFail | The password check failed. The plain-text password does not match the hashed password. |
Unsafe Debugging Functions for Showing a Password
unsafeShowPassword :: Pass -> String #
This is an unsafe function that shows a password in plain-text.
>>>
unsafeShowPasswordText $ Pass "foobar"
"foobar"
You should generally not use this function.
unsafeShowPasswordText :: Pass -> Text #
This is like unsafeShowPassword
but produces a Text
instead of a
String
.
Setup for doctests.
>>>
:set -XOverloadedStrings
Import needed functions.
>>>
import Data.Aeson (decode)
>>>
import Database.Persist.Class (PersistField(toPersistValue))
>>>
import Web.HttpApiData (parseUrlPiece)
Orphan instances
FromJSON Pass Source # | This instance allows a
There is no instance for Similarly, there is no |
FromHttpApiData Pass Source # | This instance allows a
|
parseUrlPiece :: Text -> Either Text Pass # parseHeader :: ByteString -> Either Text Pass # | |
PersistFieldSql PassHash Source # | This instance allows a |
PersistField PassHash Source # | This instance allows a
In the example above, the long We don't provide an instance of |