Phantom type for Argon2
Modulepassword-3.0.4.0Haskell2010
Data.Password.Argon2
Argon2
Argon2 is probably the newest password algorithm out there. Argon2 was
selected as the winner of the Password Hashing Competition in July 2015.
It has three variants, namely Argon2d, Argon2i and Argon2id. These protect against GPU cracking attacks, side-channel attacks, and both, respectively.
All three modes allow specification by three parameters that control:
execution time
memory required
degree of parallelism
Other algorithms
In comparison to other algorithms, Argon2 is the least "battle-tested", being the newest algorithm out there.
It is, however, recommended over Scrypt most of the time,
and it also seems like it might become the go-to password algorithm if no
vulnarabilities are discovered within the next couple of years.
- 8 types
- 9 values
- Packagepassword-3.0.4.0
- Exports17
- LanguageHaskell2010
- LicenceBSD-3-Clause
- SourceArgon2.hs
Plain-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 (Argon2)
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 (Argon2)
2 declarationsCheck a Password against a PasswordHash Argon2.
Returns PasswordCheckSuccess on success.
let pass = mkPassword "foobar"passHash <- hashPassword passcheckPassword pass passHashPasswordCheckSuccess
Returns PasswordCheckFail if an incorrect Password or PasswordHash Argon2 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 (Argon2)
6 declarationsHash a password using the Argon2 algorithm with the given Argon2Params.
N.B.: If you have any doubt in your knowledge of cryptography and/or the Argon2 algorithm, please just use hashPassword.
Advice to set the parameters:
Figure out how many threads you can use, choose "parallelism" accordingly.
Figure out how much memory you can use, choose "memory cost" accordingly.
Decide on the maximum time
xyou can spend on it, choose the largest "time cost" such that it takes less thanxwith your system and other parameter choices.
Default parameters for the Argon2 algorithm.
defaultParamsArgon2Params {argon2Salt = 16, argon2Variant = Argon2id, argon2Version = Version13, argon2MemoryCost = 65536, argon2TimeCost = 2, argon2Parallelism = 1, argon2OutputLength = 32}
Extracts Argon2Params from a PasswordHash Argon2.
Returns 'Just Argon2Params' on success.
let pass = mkPassword "foobar"passHash <- hashPassword passextractParams passHash == Just defaultParamsTrue
Parameters used in the Argon2 hashing algorithm.
Constructors
Argon2Paramsargon2Salt :: Word32Bytes to randomly generate as a unique salt, default is 16
Limits are min:
8, and max:(2 ^ 32) - 1argon2Variant :: VariantWhich variant of Argon2 to use, default is Argon2id
argon2Version :: VersionWhich version of Argon2 to use, default is Version13
argon2MemoryCost :: Word32Memory cost, given in kibibytes, default is 65536 (i.e. 64MB)
Limits are min:
8 * argon2Parallelism, and max is addressing space / 2, or(2 ^ 32) - 1, whichever is lower.argon2TimeCost :: Word32Amount of computation realized, default is 2
Limits are min:
1, and max:(2 ^ 32) - 1argon2Parallelism :: Word32Parallelism factor, default is 1
Limits are min:
1, and max:(2 ^ 24) - 1argon2OutputLength :: Word32Output key length in bytes, default is 32
Limits are min:
4, and max:(2 ^ 32) - 1
Instances2Eq, Show
Eq Argon2ParamsDefined in password-3.0.4.0 · Data.Password.Argon2Show Argon2ParamsDefined in password-3.0.4.0 · Data.Password.Argon2
Which variant of Argon2 to use. You should choose the variant that is most applicable to your intention to hash inputs.
Constructors
Argon2dArgon2d is faster than Argon2i and uses data-depending memory access, which makes it suitable for cryptocurrencies and applications with no threats from side-channel timing attacks.
Argon2iArgon2i uses data-independent memory access, which is preferred for password hashing and password-based key derivation. Argon2i is slower as it makes more passes over the memory to protect from tradeoff attacks.
Argon2idArgon2id is a hybrid of Argon2i and Argon2d, using a combination of data-depending and data-independent memory accesses, which gives some of Argon2i's resistance to side-channel cache timing attacks and much of Argon2d's resistance to GPU cracking attacks
Instances6Bounded, Enum, Eq, Ord, Read, Show
Bounded VariantDefined in cryptonite-0.30 · Crypto.KDF.Argon2Enum VariantDefined in cryptonite-0.30 · Crypto.KDF.Argon2Eq VariantDefined in cryptonite-0.30 · Crypto.KDF.Argon2Ord VariantDefined in cryptonite-0.30 · Crypto.KDF.Argon2Read VariantDefined in cryptonite-0.30 · Crypto.KDF.Argon2Show VariantDefined in cryptonite-0.30 · Crypto.KDF.Argon2
Instances6Bounded, Enum, Eq, Ord, Read, Show
Bounded VersionDefined in cryptonite-0.30 · Crypto.KDF.Argon2Enum VersionDefined in cryptonite-0.30 · Crypto.KDF.Argon2Eq VersionDefined in cryptonite-0.30 · Crypto.KDF.Argon2Ord VersionDefined in cryptonite-0.30 · Crypto.KDF.Argon2Read VersionDefined in cryptonite-0.30 · Crypto.KDF.Argon2Show VersionDefined in cryptonite-0.30 · Crypto.KDF.Argon2
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 Argon2Params and also with the given Salt instead of a random generated salt using argon2Salt from Argon2Params. (cf. hashPasswordWithParams) Using hashPasswordWithSalt is strongly disadvised and hashPasswordWithParams should be used instead. Never use a static salt in production applications!
N.B.: The salt HAS to be 8 bytes or more, or this function will throw an error!
let salt = Salt "abcdefghijklmnop"hashPasswordWithSalt defaultParams salt (mkPassword "foobar")PasswordHash {unPasswordHash = "$argon2id$v=19$m=65536,t=2,p=1$YWJjZGVmZ2hpamtsbW5vcA$BztdyfEefG5V18ZNlztPrfZaU5duVFKZiI6dJeWht0o"}
(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 16-byte Argon2 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 16instance Arbitrary Password where arbitrary = fmap mkPassword arbitrarylet testParams = defaultParams {argon2TimeCost = 1}let salt = Salt "abcdefghijklmnop"