Hash passwords with BCrypt instead of SHA1

BCrypt is regarded as a more secure alternative to hashing using message
digest algorithms, such as MD5 and SHA families [0, 1, 2]. Apart from
built-in salting it is adaptable to the increasing power of modern
processing units, which makes it more secure against brute-force cracking.

This commit makes all passwords hashed using BCrypt. The session tokens
remain generated using SHA1. Tests were updated, `rake test:units` and
`rake test:functionals` didn't report any regressions.

[0] http://bcrypt.sourceforge.net/
[1] http://en.wikipedia.org/w/index.php?title=Bcrypt&oldid=439692871
[2] eab1c72/README.md
This commit is contained in:
Jan Stępień 2011-07-23 10:52:38 +02:00
parent 0b88c72570
commit 95f0f71441
7 changed files with 24 additions and 17 deletions

View file

@ -123,7 +123,8 @@ class User < ActiveRecord::Base
return nil if candidate.nil?
if Tracks::Config.auth_schemes.include?('database')
return candidate if candidate.auth_type == 'database' && candidate.crypted_password == sha1(pass)
return candidate if candidate.auth_type == 'database' &&
BCrypt::Password.new(candidate.crypted_password) == salted(pass)
end
if Tracks::Config.auth_schemes.include?('ldap')
@ -190,7 +191,7 @@ class User < ActiveRecord::Base
end
def generate_token
self.token = Digest::SHA1.hexdigest "#{Time.now.to_i}#{rand}"
self.token = self.class.sha1 "#{Time.now.to_i}#{rand}"
end
def remember_token?
@ -212,13 +213,21 @@ class User < ActiveRecord::Base
protected
def self.salted(s)
"#{Tracks::Config.salt}--#{s}--"
end
def self.sha1(s)
Digest::SHA1.hexdigest("#{Tracks::Config.salt}--#{s}--")
Digest::SHA1.hexdigest salted s
end
def self.hash(s)
BCrypt::Password.create salted s
end
def crypt_password
return if password.blank?
write_attribute("crypted_password", self.class.sha1(password)) if password == password_confirmation
write_attribute("crypted_password", self.class.hash(password)) if password == password_confirmation
end
def password_required?
@ -229,10 +238,6 @@ protected
auth_type == 'open_id'
end
def password_matches?(pass)
crypted_password == sha1(pass)
end
def normalize_open_id_url
return if open_id_url.nil?