Created
March 6, 2012 23:35
-
-
Save e0da/1989787 to your computer and use it in GitHub Desktop.
Hashing and checking SSHA passwords in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'base64' | |
require 'digest' | |
# get 16 random hex bytes | |
# | |
def new_salt | |
16.times.inject('') {|t| t << rand(16).to_s(16)} | |
end | |
# hash the password using the given salt. If no salt is supplied, use a new | |
# one. | |
# | |
def hash_password(password, salt=new_salt) | |
"{SSHA}" + Base64.encode64("#{Digest::SHA1.digest("#{password}#{salt}")}#{salt}").chomp | |
end | |
# Check the supplied password against the given hash and return true if they | |
# match, else false. | |
# | |
def check_password(password, ssha) | |
decoded = Base64.decode64(ssha.gsub(/^{SSHA}/, '')) | |
hash = decoded[0,20] # isolate the hash | |
salt = decoded[20,-1] # isolate the salt | |
hash_password(password, salt) == ssha | |
end | |
# a single argument just requests the hash for the supplied password. two | |
# arguments check the first (a password) against the second (an SSHA hash of a | |
# password) | |
# | |
ARGV[0] = ARGV[0].gsub /^"(.*)"$/, '$1' | |
if ARGV[1] | |
puts check_password ARGV[0], ARGV[1] | |
else | |
puts hash_password ARGV[0] | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Awesome, thanks so much for this example! I made some small changes to use
SecureRandom
: