Module: RbNaCl::PasswordHash

Defined in:
lib/rbnacl/password_hash.rb,
lib/rbnacl/password_hash/argon2.rb,
lib/rbnacl/password_hash/scrypt.rb

Overview

Password hashing functions

These hash functions are designed specifically for the purposes of securely storing passwords in a way that they can be checked against a supplied password but an attacker who obtains a hash cannot easily reverse them back into the original password.

Unlike normal hash functions, which are intentionally designed to hash data as quickly as they can while remaining secure, password hashing functions are intentionally designed to be slow so they are hard for attackers to brute force.

All password hashing functions take a "salt" value which should be randomly generated on a per-password basis (using RbNaCl::Random, accept no substitutes)

All of them also take a CPU work factor, which increases the amount of computation needed to produce the digest.

Defined Under Namespace

Classes: Argon2, SCrypt

Class Method Summary collapse

Class Method Details

.argon2(password, salt, opslimit, memlimit, digest_size = 64) ⇒ String

argon2: state of the art in the design of memory-hard hashing functions (default digest algorithm).

Parameters:

  • password (String)

    to be hashed

  • salt (String)

    to make the digest unique

  • opslimit (Integer)

    the CPU cost (3..10)

  • memlimit (Integer)

    the memory cost, in bytes

  • digest_size (Integer) (defaults to: 64)

    of the output

Returns:

  • (String)

    The argon2 digest as raw bytes

Raises:

  • (CryptoError)

    If calculating the digest fails for some reason.



52
53
54
# File 'lib/rbnacl/password_hash.rb', line 52

def self.argon2(password, salt, opslimit, memlimit, digest_size = 64)
  argon2_supported? && Argon2.new(opslimit, memlimit, digest_size).digest(password, salt)
end

.argon2_str(password, opslimit = :interactive, memlimit = :interactive) ⇒ String

argon2_str: crypt-style password digest

Parameters:

  • password (String)

    to be hashed

  • opslimit (Integer) (defaults to: :interactive)

    the CPU cost (3..10)

  • memlimit (Integer) (defaults to: :interactive)

    the memory cost, in bytes

Returns:

  • (String)

    The argon2i digest as crypt-style string

Raises:

  • (CryptoError)

    If calculating the digest fails for some reason.



95
96
97
# File 'lib/rbnacl/password_hash.rb', line 95

def self.argon2_str(password, opslimit = :interactive, memlimit = :interactive)
  argon2_supported? && Argon2.new(opslimit, memlimit).digest_str(password)
end

.argon2_valid?(password, str_digest) ⇒ Boolean

argon2_valid?: verify crypt-style password digest

Parameters:

  • password (String)

    to verify

  • str_digest (String)

    to verify

Returns:

  • (Boolean)

    true if digest was created using password



105
106
107
# File 'lib/rbnacl/password_hash.rb', line 105

def self.argon2_valid?(password, str_digest)
  argon2_supported? && Argon2.digest_str_verify(password, str_digest)
end

.argon2i(password, salt, opslimit, memlimit, digest_size = 64) ⇒ String

argon2i: argon2, using argon2i digest algorithm.

Parameters:

  • password (String)

    to be hashed

  • salt (String)

    to make the digest unique

  • opslimit (Integer)

    the CPU cost (3..10)

  • memlimit (Integer)

    the memory cost, in bytes

  • digest_size (Integer) (defaults to: 64)

    of the output

Returns:

  • (String)

    The argon2i digest as raw bytes

Raises:

  • (CryptoError)

    If calculating the digest fails for some reason.



67
68
69
# File 'lib/rbnacl/password_hash.rb', line 67

def self.argon2i(password, salt, opslimit, memlimit, digest_size = 64)
  argon2_supported? && Argon2.new(opslimit, memlimit, digest_size).digest(password, salt, :argon2i)
end

.argon2id(password, salt, opslimit, memlimit, digest_size = 64) ⇒ String

argon2id: argon2, using argon2id digest algorithm.

Parameters:

  • password (String)

    to be hashed

  • salt (String)

    to make the digest unique

  • opslimit (Integer)

    the CPU cost (3..10)

  • memlimit (Integer)

    the memory cost, in bytes

  • digest_size (Integer) (defaults to: 64)

    of the output

Returns:

  • (String)

    The argon2id digest as raw bytes

Raises:

  • (CryptoError)

    If calculating the digest fails for some reason.



82
83
84
# File 'lib/rbnacl/password_hash.rb', line 82

def self.argon2id(password, salt, opslimit, memlimit, digest_size = 64)
  argon2_supported? && Argon2.new(opslimit, memlimit, digest_size).digest(password, salt, :argon2id)
end

.scrypt(password, salt, opslimit = SCrypt::OPSLIMIT_SENSITIVE, memlimit = SCrypt::MEMLIMIT_SENSITIVE, digest_size = 64) ⇒ String

scrypt: the original sequential memory-hard password hashing function.

Parameters:

  • password (String)

    to be hashed

  • salt (String)

    to make the digest unique

  • opslimit (Integer) (defaults to: SCrypt::OPSLIMIT_SENSITIVE)

    the CPU cost (e.g. 2**20)

  • memlimit (Integer) (defaults to: SCrypt::MEMLIMIT_SENSITIVE)

    the memory cost (e.g. 2**24)

  • digest_size (Integer) (defaults to: 64)

    of the output

Returns:

  • (String)

    The scrypt digest as raw bytes

Raises:

  • (CryptoError)

    If calculating the digest fails for some reason.



35
36
37
38
# File 'lib/rbnacl/password_hash.rb', line 35

def self.scrypt(password, salt, opslimit = SCrypt::OPSLIMIT_SENSITIVE, memlimit = SCrypt::MEMLIMIT_SENSITIVE,
                digest_size = 64)
  SCrypt.new(opslimit, memlimit, digest_size).digest(password, salt)
end