Skip to content

Updating an app's hashing algorithm

David Whitlock edited this page Jul 7, 2020 · 2 revisions

This is a guide on how you can update your app's hashing algorithm - from, for example, Bcrypt to Argon2, or vice versa.

There are several different ways of handling this. More information can be found here and here. This guide will look at the updating the hash (stored in the database) upon successful login method.

Updating the hash upon successful login

Outline of this method:

  1. when a user tries to log in, search for the user data in the database (using the user's email or username)
  2. check the password hash to see what algorithm was used to generate it
    1. if it is the new algorithm, verify the password as normal
    2. if it is the old algorithm, verify the password
      1. if the password is correct, hash the password using the new algorithm and save it to the database
      2. if the password is not correct, return false

The verify_password function below provides an example of updating the hashes from Bcrypt to Argon2 (you will need to write the update_db function yourself).

def verify_password(_, nil), do: false

def verify_password(password, %{password_hash: hash} = user) do
  if String.starts_with?(hash, "$argon2") do
    Argon2.verify_pass(password, hash)
  else
    Bcrypt.verify_pass(password, hash) && update_db(user, password)
    true
  end
end

Checking the password hashing algorithm

In the example code above, the prefix of the password hash is checked to see that it is "$argon2". For Bcrypt, change this check to "$2", and for Pbkdf2, change it to "$pbkdf2".