bcrypt_elixir v2.0.3 Bcrypt View Source
Bcrypt password hashing library main module.
This module implements the Comeonin and Comeonin.PasswordHash behaviours, providing the following functions:
add_hash/2
- takes a password as input and returns a map containing the password hashcheck_pass/3
- takes a user struct and password as input and verifies the passwordno_user_verify/1
- runs the hash function, but always returns falsehash_pwd_salt/2
- hashes the password with a randomly-generated saltverify_pass/2
- verifies a password
For a lower-level API, see Bcrypt.Base.
Configuration
The following parameter can be set in the config file:
log_rounds
- the computational cost as number of log rounds- the default is 12 (2^12 rounds)
If you are hashing passwords in your tests, it can be useful to add
the following to the config/test.exs
file:
config :bcrypt_elixir, log_rounds: 4
NB. do not use this value in production.
Options
In addition to the options listed below, the add_hash
, no_user_verify
and hash_pwd_salt
functions all take a log_rounds
option, which can be
used to override the value in the config.
add_hash
hash_key
- the key used in the map for the password hash- the default is
password_hash
- the default is
check_pass
hash_key
- the key used in the user struct for the password hash- if this is not set,
check_pass
will look forpassword_hash
, and thenencrypted_password
- if this is not set,
hide_user
- runno_user_verify
to prevent user enumeration- the default is true
- set this to false if you do not want to hide usernames
Examples
The following examples show how to hash a password with a randomly-generated salt and then verify a password:
iex> hash = Bcrypt.hash_pwd_salt("password")
...> Bcrypt.verify_pass("password", hash)
true
iex> hash = Bcrypt.hash_pwd_salt("password")
...> Bcrypt.verify_pass("incorrect", hash)
false
add_hash
The put_pass_hash
function below is an example of how you can use
add_hash
to add the password hash to the Ecto changeset.
defp put_pass_hash(%Ecto.Changeset{valid?: true, changes:
%{password: password}} = changeset) do
change(changeset, Bcrypt.add_hash(password))
end
defp put_pass_hash(changeset), do: changeset
This function will return a changeset with %{password_hash: password_hash, password: nil}
added to the changes
map.
check_pass
The following is an example of calling this function with no options:
def verify_user(%{"password" => password} = params) do
params
|> Accounts.get_by()
|> Bcrypt.check_pass(password)
end
The Accounts.get_by
function in this example takes the user parameters
(for example, email and password) as input and returns a user struct or nil.
Bcrypt
Bcrypt is a key derivation function for passwords designed by Niels Provos and David Mazières. Bcrypt is an adaptive function, which means that it can be configured to remain slow and resistant to brute-force attacks even as computational power increases.
Bcrypt versions
This bcrypt implementation is based on the latest OpenBSD version, which
fixed a small issue that affected some passwords longer than 72 characters.
By default, it produces hashes with the prefix $2b$
, and it can check
hashes with either the $2b$
prefix or the older $2a$
prefix.
It is also possible to generate hashes with the $2a$
prefix by running
the following command:
Bcrypt.Base.hash_password("hard to guess", Bcrypt.gen_salt(12, true))
This option should only be used if you need to generate hashes that are then checked by older libraries.
The $2y$
prefix is not supported. For advice on how to use hashes with the
$2y$
prefix, see this issue.
Hash the password with a salt which is randomly generated.
Link to this section Summary
Functions
Generate a salt for use with the Bcrypt.Base.hash_password
function
Link to this section Functions
Generate a salt for use with the Bcrypt.Base.hash_password
function.
The log_rounds parameter determines the computational complexity of the generation of the password hash. Its default is 12, the minimum is 4, and the maximum is 31.
The legacy
option is for generating salts with the old $2a$
prefix.
Only use this option if you need to generate hashes that are then checked
by older libraries.