Module: Hashpasswd

Defined in:
lib/hashpasswd.rb

Constant Summary collapse

HASH_SECTIONS =
4
ITERATIONS_INDEX =
1
SALT_INDEX =
2
HASH_INDEX =
3
DEFAULT_DELIMETER =
':'

Class Method Summary collapse

Class Method Details

.createhash(password, options = {}) ⇒ String

Creates a hash from a plain text password

Parameters:

  • password (String)

    A plain text password

  • options (Hash{Symbol => String, Number}) (defaults to: {})

Options Hash (options):

  • :pbkdf2_iterations (Int) — default: 2000

    The PBKDF2 iteration count

  • :salt_byte_size (Int) — default: 24

    The byte size for the salt

  • :hash_byte_size (Int) — default: 24

    The byte size for the hash

  • :delimiter (String) — default: ':'

    The delimeter for the hash string, changing the delimiter is not recommended as you will have to remember it and supply it as an option to validatepasswd()

  • :digest (String) — default: 'SHA1'

    The digest, can be any digest supported by OpenSSL on your sytem (eg ‘SHA224’, ‘SHA256’, ‘SHA384’ or ‘SHA512’)

Returns:

  • (String)

    the hash as “<digest>:<pbkdf2_iterations>:<salt>:<hash>”



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/hashpasswd.rb', line 21

def self.createhash(password, options={})
  @pbkdf2_iterations = options[:pbkdf2_iterations] || 2000
  @salt_byte_size = options[:salt_byte_size] ||24
  @hash_byte_size = options[:hash_byte_size]|| 24
  @delimeter = options[:delimter] || ':'
  @digest = options[:digest] || 'SHA1'

  salt = SecureRandom.base64(@salt_byte_size)
  pbkdf2 = OpenSSL::PKCS5::pbkdf2_hmac(
    password,
    salt,
    @pbkdf2_iterations,
    @hash_byte_size,
    @digest
 )
  return [@digest, @pbkdf2_iterations, salt, Base64.encode64(pbkdf2)].join(@delimeter)
end

.getconstantsHash

Get the values of all constants

Parameters:

  • none

Returns:

  • (Hash)

    of all constants



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

def self.getconstants()
  return {:HASH_SECTIONS => HASH_SECTIONS, :ITERATIONS_INDEX => ITERATIONS_INDEX, :SALT_INDEX => SALT_INDEX, :HASH_INDEX => HASH_INDEX, :DEFAULT_DELIMETER => DEFAULT_DELIMETER}
end

.validatepasswd(password, hash, options = {}) ⇒ Boolean

Validates a password against a hash

Parameters:

  • password (String)

    A plain text password

  • hash (String)

    “<digest>:<pbkdf2_iterations>:<salt>:<hash>”

  • options (Hash{Symbol => String}) (defaults to: {})

Options Hash (options):

  • :delimiter (String) — default: ':'

    The delimeter for the hash string, only necessary if you did not use the default delimiter (‘:’) when creating the hash.

Returns:

  • (Boolean)

    True if the password matches the hash; False if not.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/hashpasswd.rb', line 46

def self.validatepasswd(password, hash, options={})
  @delimeter = options[:delimter] || ':'

  params = hash.split(@delimeter)
  return false if params.length != HASH_SECTIONS

  pbkdf2 = Base64.decode64(params[HASH_INDEX])
  testhash = OpenSSL::PKCS5::pbkdf2_hmac(
    password,
    params[SALT_INDEX],
    params[ITERATIONS_INDEX].to_i,
    pbkdf2.length,
    params[0] 
 )

  return pbkdf2 == testhash
end