ログイン分野において最も重要なのは、
全てのパスワードに常にソルトとハッシュをかける
ことである。
ソルトとは、ユーザごとに設定したパスワードが同じものであっても、ハッシュによって得られる値がユーザによって違うものになるようにするプロセスである。
ソルト化しなかったパスワードはレインボー攻撃に弱くなる。
(ここではレインボー攻撃については割愛する)
次は、ソルトを適用したログイン名とパスワードの例である。
salt.rb
# -*- coding: utf-8 -*-
require 'digest/sha1'
$hashes = { }
$salts = { }
def hash(password, salt)
# hash化の際にsaltを含む
Digest::SHA1.hexdigest("#{salt}#{password}")
end
def generate_salt(login)
Digest::SHA1.hexdigest("#{Time.now.to_s}#{login}")
end
def store_password(login, password)
# hashを作成する前に、ユーザごとのsaltを作成する
salt = $salts[login] = generate_salt(login)
# 作成したsaltを含ませて、パスワードにhashをかける
$hashes[login] = hash(password, salt)
end
def verify_password(login, password)
$hashes[login] == hash(password, $salts[login])
end
store_password('tak158', 'password')
store_password('snthd', 'password')
puts $hashes
puts $salts
puts verify_password('tak158', 'password') # => true
puts verify_password('tak158', 'pass') # => false
puts verify_password('snthd', 'password') # => true
この方法では、同じパスワードからhashしても異なる値が得られるのでレインボー攻撃に強くなる。