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
endNá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