RSS Amplifier

Shorts · Mar 24, 2019

Argon2 with Devise

0
Sign in to vote or save

ankane.org

bcrypt has been a great choice for safely storing passwords. However, as time has passed, a better alternative has emerged: Argon2. OWASP now recommends Argon2 for new applications. With a little bit of code, you can use Argon2 with Devise.

Devise supports custom encryptors. However, it requires a separate column to store a salt, which isn’t needed as Argon2 stores the salt in the password hash (like bcrypt).

Instead, add argon2 to your Gemfile:

gem 'argon2', '>= 2'

And create config/initializers/devise_argon2.rb with:

module Argon2Encryptor
  def digest(klass, password)
    if klass.pepper.present?
      password = "#{password}#{klass.pepper}"
    end
    ::Argon2::Password.create(password)
  end
  def compare(klass, hashed_password, password)
    return false if hashed_password.blank?
    if hashed_password.start_with?("$argon2")
      if klass.pepper.present?
        password = "#{password}#{klass.pepper}"
      end
      ::Argon2::Password.verify_password(password, hashed_password)
    else
      super
    end
  end
end
Devise::Encryptor.singleton_class.prepend(Argon2Encryptor)

All new passwords will be hashed with Argon2. For existing passwords, rotate to Argon2 when a user signs in. Add to your model:

class User < ApplicationRecord
  def valid_password?(password)
    valid = super
    if valid && !encrypted_password.start_with?("$argon2")
      self.password = password
      save(validate: false)
    end
    valid
  end
end

You can also rehash all passwords at once, but it’s a bit more complicated.

Congrats, your password storage is even stronger!

All code examples are public domain.
Use them however you’d like (licensed under CC0).

Read the original on ankane.org

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.