Phantom type for scrypt
Modulepassword-3.0.4.0Haskell2010
Data.Password.Scrypt
scrypt
The scrypt algorithm is a fairly new one. First published
in 2009, but published by the IETF in 2016 as RFC 7914.
Originally used for the Tarsnap backup service, it is
designed to be costly by requiring large amounts of memory.
Other algorithms
scrypt does increase the memory requirement in contrast to
Bcrypt and PBKDF2, but it
turns out it is not as optimal as it could be, and thus others have set out
to search for other algorithms that do fulfill on their promises.
Argon2 seems to be the winner in that search.
That is not to say using scrypt somehow means your passwords
won't be properly protected. The cryptography is sound and
thus is fine for protection against brute-force attacks.
Because of the memory cost, it is generally advised to use
Bcrypt if you're not sure this might be a
problem on your system.
- 6 types
- 9 values
- Packagepassword-3.0.4.0
- Exports15
- LanguageHaskell2010
- LicenceBSD-3-Clause
- SourceScrypt.hs
Algorithm
1 declarationPlain-text Password
2 declarationsA plain-text password.
This represents a plain-text password that has NOT been hashed.
You should be careful with Password. Make sure not to write it to logs or store it in a database.
You can construct a Password by using the mkPassword function or as literal
strings together with the OverloadedStrings pragma (or manually, by using
fromString on a String). Alternatively, you could also use some of the
instances in the password-instances
library.
Construct a Password
Hash Passwords (scrypt)
2 declarationsA hashed password.
This represents a password that has been put through a hashing function. The hashed password can be stored in a database.
Constructors
Instances4Eq, Ord, Read, Show
Eq (PasswordHash a)Defined in password-types-1.0.0.0 · Data.Password.TypesOrd (PasswordHash a)Defined in password-types-1.0.0.0 · Data.Password.TypesRead (PasswordHash a)Defined in password-types-1.0.0.0 · Data.Password.TypesShow (PasswordHash a)Defined in password-types-1.0.0.0 · Data.Password.Types
Verify Passwords (scrypt)
2 declarationsCheck a Password against a PasswordHash Scrypt.
Returns PasswordCheckSuccess on success.
let pass = mkPassword "foobar"passHash <- hashPassword passcheckPassword pass passHashPasswordCheckSuccess
Returns PasswordCheckFail if an incorrect Password or PasswordHash Scrypt is used.
let badpass = mkPassword "incorrect-password"checkPassword badpass passHashPasswordCheckFail
This should always fail if an incorrect password is given.
\(Blind badpass) -> let correctPasswordHash = hashPasswordWithSalt testParams salt "foobar" in checkPassword badpass correctPasswordHash == PasswordCheckFailThe result of checking a password against a hashed version. This is
returned by the checkPassword functions.
Constructors
PasswordCheckSuccessThe password check was successful. The plain-text password matches the hashed password.
PasswordCheckFailThe password check failed. The plain-text password does not match the hashed password.
Instances3Eq, Read, Show
Eq PasswordCheckDefined in password-3.0.4.0 · Data.Password.InternalRead PasswordCheckDefined in password-3.0.4.0 · Data.Password.InternalShow PasswordCheckDefined in password-3.0.4.0 · Data.Password.Internal
Hashing Manually (scrypt)
4 declarationsHash a password using the Scrypt algorithm with the given ScryptParams.
N.B.: If you have any doubt in your knowledge of cryptography and/or the Scrypt algorithm, please just use hashPassword.
Advice for setting the parameters:
Memory used is about:
(2 ^ scryptRounds) * scryptBlockSize * 128Increasing scryptBlockSize and scryptRounds will increase CPU time and memory used.
Increasing scryptParallelism will increase CPU time. (since this implementation, like most, runs the scryptParallelism parameter in sequence, not in parallel)
Default parameters for the Scrypt algorithm.
defaultParamsScryptParams {scryptSalt = 32, scryptRounds = 14, scryptBlockSize = 8, scryptParallelism = 1, scryptOutputLength = 64}
Extracts ScryptParams from a PasswordHash Scrypt.
Returns 'Just ScryptParams' on success.
let pass = mkPassword "foobar"passHash <- hashPassword passextractParams passHash == Just defaultParamsTrue
Parameters used in the Scrypt hashing algorithm.
Constructors
ScryptParamsscryptSalt :: Word32Bytes to randomly generate as a unique salt, default is 32
scryptRounds :: Word32log2(N) rounds to hash, default is 14 (i.e. 2^14 rounds)
scryptBlockSize :: Word32Block size, default is 8
Limits are min:
1, and max:scryptBlockSize * scryptParallelism < 2 ^ 30scryptParallelism :: Word32Parallelism factor, default is 1
Limits are min:
0, and max:scryptBlockSize * scryptParallelism < 2 ^ 30scryptOutputLength :: Word32Output key length in bytes, default is 64
Instances2Eq, Show
Eq ScryptParamsDefined in password-3.0.4.0 · Data.Password.ScryptShow ScryptParamsDefined in password-3.0.4.0 · Data.Password.Scrypt
Hashing with salt (DISADVISED)
Hashing with a set Salt is almost never what you want to do. Use hashPassword or hashPasswordWithParams to have automatic generation of randomized salts.
Hash a password with the given ScryptParams and also with the given Salt instead of a randomly generated salt using scryptSalt from ScryptParams. Using hashPasswordWithSalt is strongly disadvised and hashPasswordWithParams should be used instead. Never use a static salt in production applications!
The resulting PasswordHash has the parameters used to hash it, as well as the
Salt appended to it, separated by |.
The input Salt and resulting PasswordHash are both base64 encoded.
let salt = Salt "abcdefghijklmnopqrstuvwxyz012345"hashPasswordWithSalt defaultParams salt (mkPassword "foobar")PasswordHash {unPasswordHash = "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 hashPassword. hashPassword generates a new Salt everytime it is called.)
Generate a random 32-byte scrypt salt
A salt used by a hashing algorithm.
Constructors
Unsafe debugging function to show a Password
1 declarationThis is an unsafe function that shows a password in plain-text.
unsafeShowPassword ("foobar" :: Password)"foobar"
You should generally not use this function in production settings, as you don't want to accidentally print a password anywhere, like logs, network responses, database entries, etc.
This will mostly be used by other libraries to handle the actual password internally, though it is conceivable that, even in a production setting, a password might have to be handled in an unsafe manner at some point.
Setup for doctests.
0 declarations:set -XFlexibleInstances:set -XOverloadedStrings
Import needed libraries.
import Data.Password.Typesimport Data.ByteString (pack)import Test.QuickCheck (Arbitrary(arbitrary), Blind(Blind), vector)import Test.QuickCheck.Instances.Text ()
instance Arbitrary (Salt a) where arbitrary = Salt . pack <$> vector 32instance Arbitrary Password where arbitrary = fmap mkPassword arbitrarylet salt = Salt "abcdefghijklmnopqrstuvwxyz012345"let testParams = defaultParams {scryptRounds = 10}