module JunglePath::Authentication::PasswordHash

Salted password hashing with PBKDF2-SHA1. Authors: @RedragonX (dicesoft.net), havoc AT defuse.ca www: crackstation.net/hashing-security.htm

Constants

HASH_BYTE_SIZE
HASH_INDEX
HASH_SECTIONS
ITERATIONS_INDEX
PBKDF2_ITERATIONS

The following constants can be changed without breaking existing hashes.

SALT_BYTE_SIZE
SALT_INDEX
SECTION_DELIMITER

Public Class Methods

assert( truth, msg ) click to toggle source
# File lib/jungle_path/authentication/password_hash.rb, line 112
def self.assert( truth, msg )
  if truth
    puts "PASS [#{msg}]"
  else
    puts "FAIL [#{msg}]"
    @@allPass = false
  end
end
create_hash( password ) click to toggle source

Returns a salted PBKDF2 hash of the password.

# File lib/jungle_path/authentication/password_hash.rb, line 54
def self.create_hash( password )
  salt = SecureRandom.base64( SALT_BYTE_SIZE )
  pbkdf2 = OpenSSL::PKCS5::pbkdf2_hmac_sha1(
    password,
    salt,
    PBKDF2_ITERATIONS,
    HASH_BYTE_SIZE
  )
  return ["sha1", PBKDF2_ITERATIONS, salt, Base64.encode64( pbkdf2 )].join( SECTION_DELIMITER )
end
runSelfTests() click to toggle source

Run tests to ensure the module is functioning properly. Returns true if all tests succeed, false if not.

# File lib/jungle_path/authentication/password_hash.rb, line 84
def self.runSelfTests
  puts "Sample hashes:"
  3.times { puts create_hash("password") }

  puts "\nRunning self tests..."
  @@allPass = true

  correctPassword = 'aaaaaaaaaa'
  wrongPassword = 'aaaaaaaaab'
  hash = create_hash(correctPassword)

  assert( validate_password( correctPassword, hash ) == true, "correct password" )
  assert( validate_password( wrongPassword, hash ) == false, "wrong password" )

  h1 = hash.split( SECTION_DELIMITER )
  h2 = create_hash( correctPassword ).split( SECTION_DELIMITER )
  assert( h1[HASH_INDEX] != h2[HASH_INDEX], "different hashes" )
  assert( h1[SALT_INDEX] != h2[SALT_INDEX], "different salt" )

  if @@allPass
    puts "*** ALL TESTS PASS ***"
  else
    puts "*** FAILURES ***"
  end

  return @@allPass
end
validate_password( password, correctHash ) click to toggle source

Checks if a password is correct given a hash of the correct one. correctHash must be a hash string generated with create_hash.

# File lib/jungle_path/authentication/password_hash.rb, line 67
def self.validate_password( password, correctHash )
  params = correctHash.split( SECTION_DELIMITER )
  return false if params.length != HASH_SECTIONS

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

  return pbkdf2 == testHash
end