class HTAuth::Md5
an implementation of the MD5 based encoding algorithm as used in the apache htpasswd -m option
Constants
- DIGEST_LENGTH
- ENTRY_REGEX
- PAD_LENGTH
- PREFIX
- SALT_CHARS_STR
Public Class Methods
extract_salt_from_existing_password_field(existing)
click to toggle source
# File lib/htauth/md5.rb, line 26 def self.extract_salt_from_existing_password_field(existing) p = existing.split("$") return p[2] end
handles?(password_entry)
click to toggle source
# File lib/htauth/md5.rb, line 22 def self.handles?(password_entry) ENTRY_REGEX.match?(password_entry) end
new(params = {})
click to toggle source
# File lib/htauth/md5.rb, line 31 def initialize(params = {}) if existing = (params['existing'] || params[:existing]) then @salt = self.class.extract_salt_from_existing_password_field(existing) else @salt = params[:salt] || params['salt'] || gen_salt end end
Public Instance Methods
encode(password)
click to toggle source
this algorigthm pulled straight from apr_md5_encode() and converted to ruby syntax
# File lib/htauth/md5.rb, line 40 def encode(password) primary = ::Digest::MD5.new primary << password primary << PREFIX primary << @salt md5_t = ::Digest::MD5.digest("#{password}#{@salt}#{password}") l = password.length while l > 0 do slice_size = ( l > DIGEST_LENGTH ) ? DIGEST_LENGTH : l primary << md5_t[0, slice_size] l -= DIGEST_LENGTH end # weirdness l = password.length while l != 0 case (l & 1) when 1 primary << 0.chr when 0 primary << password[0,1] end l >>= 1 end pd = primary.digest encoded_password = "#{PREFIX}#{@salt}$" # apr_md5_encode has this comment about a 60Mhz Pentium above this loop. 1000.times do |x| ctx = ::Digest::MD5.new ctx << (( ( x & 1 ) == 1 ) ? password : pd[0,DIGEST_LENGTH]) (ctx << @salt) unless ( x % 3 ) == 0 (ctx << password) unless ( x % 7 ) == 0 ctx << (( ( x & 1 ) == 0 ) ? password : pd[0,DIGEST_LENGTH]) pd = ctx.digest end pd = pd.bytes.to_a l = (pd[ 0]<<16) | (pd[ 6]<<8) | pd[12] encoded_password << to_64(l, 4) l = (pd[ 1]<<16) | (pd[ 7]<<8) | pd[13] encoded_password << to_64(l, 4) l = (pd[ 2]<<16) | (pd[ 8]<<8) | pd[14] encoded_password << to_64(l, 4) l = (pd[ 3]<<16) | (pd[ 9]<<8) | pd[15] encoded_password << to_64(l, 4) l = (pd[ 4]<<16) | (pd[10]<<8) | pd[ 5] encoded_password << to_64(l, 4) encoded_password << to_64(pd[11],2) return encoded_password end