Skip to content

Instantly share code, notes, and snippets.

@lkfken
Created May 8, 2017 23:52
Show Gist options
  • Save lkfken/f852aab9b6581addf5a72a250fb6d1ca to your computer and use it in GitHub Desktop.
Save lkfken/f852aab9b6581addf5a72a250fb6d1ca to your computer and use it in GitHub Desktop.
To demostrate how to add/use salt on password
require 'bcrypt'
require 'pp'
require 'base64'
require 'yaml'
require 'ostruct'
SECRET = 'my password'
puts '********** Base64 (not safe because it produces the same string every time)**********'
enc_64_string = "bXkgcGFzc3dvcmQ=\n"
enc = Base64.encode64(SECRET)
puts ['Same?', enc.to_s == enc_64_string].join(' ')
pp enc
puts plain = Base64.decode64(enc)
puts '********** create database record **********'
BCrypt::Engine.cost = 4 # default is 10
bcrypt_from_password = BCrypt::Password.create(SECRET)
# salt includes information on version and cost
# raw_hash = salt + checksum
row = { password: SECRET,
version: bcrypt_from_password.version,
cost: bcrypt_from_password.cost,
salt: bcrypt_from_password.salt,
checksum: bcrypt_from_password.checksum,
raw_hash: bcrypt_from_password.to_s }
# save results
results = YAML::load_file('./results.yml') rescue Array.new
results << row
File.open('./results.yml', 'w') { |f| f.puts results.to_yaml }
# simulate DB record
db_record = OpenStruct.new(:username => 'user',
salt: results[rand(results.size - 1)][:salt],
raw_hash: results[rand(results.size - 1)][:raw_hash])
pp db_record
puts '********** scenario 1 (password match) **********'
user_input = OpenStruct.new(:password => 'my password', :username => 'user')
password = BCrypt::Password.new(db_record.raw_hash)
puts ['match:', BCrypt::Password.new(password).is_password?(user_input.password)].join(' ')
puts '********** scenario 2 (password not match) **********'
user_input = OpenStruct.new(:password => 'wrong password', :username => 'user')
password = BCrypt::Password.new(db_record.raw_hash)
puts ['match:', BCrypt::Password.new(password).is_password?(user_input.password)].join(' ')
# scenario 3 and 4 are comparing raw hash. It's not recommended because one needs to store the salt and the raw hash to the database.
puts '********** scenario 3 **********'
user_input = OpenStruct.new(:password => 'my password', :username => 'user')
hash_secret = BCrypt::Engine.hash_secret(user_input.password, db_record.salt)
puts ['User Hash Secret:', hash_secret].join(' ')
puts ['DB Hash Secret:', db_record.raw_hash].join(' ')
puts ['match:', hash_secret == db_record.raw_hash].join(' ')
puts '********** scenario 4 **********'
user_input = OpenStruct.new(:password => 'wrong password', :username => 'user')
hash_secret = BCrypt::Engine.hash_secret(user_input.password, db_record.salt)
puts ['User Hash Secret:', hash_secret].join(' ')
puts ['DB Hash Secret:', db_record.raw_hash].join(' ')
puts ['match:', hash_secret == db_record.raw_hash].join(' ')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment