Comeonin v4.1.2 Comeonin.Pbkdf2 View Source
Password hashing module using the Pbkdf2 algorithm.
For more information about the Pbkdf2 algorithm, see the Choosing an algorithm
section in the Comeonin documentation.
For a lower-level API, see Pbkdf2.Base
.
Link to this section Summary
Functions
Hash a password and return it in a map, with the password set to nil
Check the password by comparing its hash with the password hash found in a user struct, or map
Check the password by comparing it with the stored hash
Run a dummy check, which always returns false, to make user enumeration more difficult
Hash the password with a randomly-generated salt
Print out a report to help you configure the hash function
Link to this section Functions
Hash a password and return it in a map, with the password set to nil.
Options
This function uses Pbkdf2.hash_pwd_salt
as the hashing function.
In addition to the options for hash_pwd_salt, there is also the following
option:
:hash_key
- the name of the key for the password hash- the default is
:password_hash
- the default is
Example with Ecto
In this example, the create_changeset
function below shows how a new
user can be created:
def create_changeset(%User{} = user, attrs) do
user
|> changeset(attrs)
|> validate_password(:password)
|> put_pass_hash()
end
The validating the password
section will then look at writing
a custom validator (validate_password), and the adding the password hash
section will cover the use of the add_hash
function (in put_pass_hash).
Validating the password
This section can be skipped if you are using a frontend solution to validating the password.
The following is a basic example of the validate_password
function:
def validate_password(changeset, field, options \ []) do
validate_change(changeset, field, fn _, password ->
case valid_password?(password) do
{:ok, _} -> []
{:error, msg} -> [{field, options[:message] || msg}]
end
end)
end
In the example below, the valid_password?
function checks that
the password is at least 8 characters long.
defp valid_password?(password) when byte_size(password) > 7 do
{:ok, password}
end
defp valid_password?(_), do: {:error, "The password is too short"}
Alternatively, you could use a dedicated password strength checker, such as not_qwerty123.
For more information about password strength rules, see the latest NIST guidelines.
Adding the password hash
In the following example, add_hash
is used in the put_pass_hash
function:
defp put_pass_hash(%Ecto.Changeset{valid?: true, changes:
%{password: password}} = changeset) do
change(changeset, Comeonin.Pbkdf2.add_hash(password))
end
defp put_pass_hash(changeset), do: changeset
Check the password by comparing its hash with the password hash found in a user struct, or map.
After finding the password hash in the user struct, the password
is checked by comparing it with the hash. Then the function returns
{:ok, user}
or {:error, message}
. Note that the error message is
meant to be used for logging purposes only; it should not be passed
on to the end user.
Options
:hide_user
- run a dummy verify function if the user is not found- see the documentation for
Pbkdf2.no_user_verify
for more details - the default is true
- see the documentation for
:hash_key
- the name of the key for the password hash - in the user struct- if you use
:password_hash
or:encrypted_password
, you do not need to set this
- if you use
Examples
The following is a simple example using Phoenix 1.3:
def verify(attrs) do
MyApp.Accounts.get_by(attrs)
|> Comeonin.Pbkdf2.check_pass(password)
end
Check the password by comparing it with the stored hash.
For more details, see the documentation for Pbkdf2.verify_pass
.
Run a dummy check, which always returns false, to make user enumeration more difficult.
For more details, see the documentation for Pbkdf2.no_user_verify
.
Hash the password with a randomly-generated salt.
For more details, see the documentation for Pbkdf2.hash_pwd_salt
and Pbkdf2.Base.hash_password
.
Print out a report to help you configure the hash function.
For more details, see the documentation for Pbkdf2.Stats.report
.