Class: Devise::Hashable::Strategy::Argon2

Inherits:
Base
  • Object
show all
Defined in:
lib/devise/hashable/strategy/argon2.rb

Overview

Argon2 password hashing

Class Method Summary collapse

Class Method Details

.compare(_klass, encrypted_password, password) ⇒ Boolean

Verifies a plain-text password against an Argon2id hash.

Parameters:

  • _klass (Class)

    the Devise model class (unused; Argon2 encodes its own parameters in the hash)

  • encrypted_password (String)

    the stored Argon2id hash

  • password (String)

    the plain-text password to verify

Returns:

  • (Boolean)

    true when the password matches



18
19
20
# File 'lib/devise/hashable/strategy/argon2.rb', line 18

def compare(_klass, encrypted_password, password)
  ::Argon2::Password.verify_password(password, encrypted_password)
end

.digest(klass, password) ⇒ String

Hashes a plain-text password with Argon2id.

Parameters:

  • klass (Class)

    the Devise model class, read for argon2_profile

  • password (String)

    the plain-text password to hash

Returns:

  • (String)

    the encoded Argon2id hash

Raises:

  • (ArgumentError)

    when argon2_profile is not a known profile



28
29
30
# File 'lib/devise/hashable/strategy/argon2.rb', line 28

def digest(klass, password)
  ::Argon2::Password.new(profile: base_configs(klass)[:argon2_profile]).create(password)
end

.password_configurations_match?(klass, encrypted_password) ⇒ Boolean

Returns:

  • (Boolean)


32
33
34
35
36
37
# File 'lib/devise/hashable/strategy/argon2.rb', line 32

def password_configurations_match?(klass, encrypted_password)
  current_password_configs = split_password_hash(encrypted_password)
  required_password_configs = base_configs(klass)

  current_password_configs[:mtp] == profile_parameters(required_password_configs[:argon2_profile])
end

.split_password_hash(encrypted_password) ⇒ Object

rubocop:disable Metrics/MethodLength



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/devise/hashable/strategy/argon2.rb', line 39

def split_password_hash(encrypted_password) # rubocop:disable Metrics/MethodLength
  split_digest = encrypted_password.split("$")

  raise InvalidPasswordHash, "Invalid password hash for Argon2" unless split_digest.length == 6

  _, strategy, version, mtp, salt, digest = split_digest

  raise InvalidPasswordHash, "Invalid password hash strategy for Argon2" unless strategy == "argon2id"

  {
    strategy: strategy,
    version: version,
    mtp: mtp,
    salt: salt,
    digest: digest
  }
end