Před hashováním upravíme heslo tím že k němu přidáme sůl (další text). Bez znalosti této soli nikdo nemůže zopakovat hashování hesel.
Příklad 47.23. Heslo se solí v modelu
class User < ActiveRecord::Base … private def self.hash_with_salt(password) retuirn Digest::SHA1.hexdigest("Put salt on the #{password}") end end
Náhodná sůl v hesle
$
script/generate migration AddPasswordSaltexists db/migrate create db/migrate/006_add_password_salt.rb
class AddPasswordSalt < ActiveRecord::Migration
def self.up
add_column :users, :salt, :string, :limit => 40
User.find(:all).each do |user|
user.password = user.hashed_password
user.save
end
end
def self.down
# Nevratná změna v databázi.
remove_column :user, :salt
end
end
$
rake db:migrate
class User < ActiveRecord::Base … attr_protected :hashed_password, :salt def before_create self.salt = User.make_salt(self.login) self.hashed_password = User.hash_with_salt(@password, self.salt) end def before_update unless @password.blank? self.salt = User.make_salt(self.username) if self.salt.blank? self.hashed_password = User.hash_with_salt(@password, salt.salt) end end def self.authenticate(username = '', password = '') user = self.find(:first, :conditions => ["username = ?", username]) return (user && user.authenticated?) ? user : nil end def authenticated?(password = '') self.hashed_password == User.hash_with_salt(password, self.salt) end private def self.make_salt(string) return Digest::SHA1.hexdigest(string.to_s + Time.now.to_s) end def self.hash_with_salt(password, salt) return Digest::SHA1.hexdigest("Put #{salt} on the #{password}") end … end