Advanced Rails - Building Industrial-Strength Web Apps in Record Time

(Tuis.) #1

128 | Chapter 5: Security


Let’s examine the reasoning behind this rule. Hashing passwords prevents them from
being recovered if the database or source code is compromised. Salting them pro-
tects them from rainbow attacks.


Saltingis the process of ensuring that the same password hashes to different values
for different users. Consider the following code, which hashes but does not salt.


require 'digest/sha1'

$hashes = {}

def hash(password)
Digest::SHA1.hexdigest(password)
end

def store_password(login, password)
$hashes[login] = hash(password)
end

def verify_password(login, password)
$hashes[login] == hash(password)
end

store_password('alice', 'kittens')
store_password('bob', 'kittens')

$hashes # => {"alice"=>"3efd62ee86d4a141c3e671d86ba1579f934cf04d",
# "bob"=> "3efd62ee86d4a141c3e671d86ba1579f934cf04d"}

verify_password('alice', 'kittens') # => true
verify_password('alice', 'mittens') # => false
verify_password('bob', 'kittens') # => true

Although this is more secure than storing the passwords in plain text, it is still insecure;
anyone who has the hash file can tell that Alice and Bob have the same password.


More importantly, this scheme is vulnerable to arainbow attack. An attacker can
precomputerainbow tablesby running every word in a dictionary through thehash
function. He can then compare each hash in the rainbow table to each hash in the
password file. Since a password always hashes to the same value, the attacker obtains
all the dictionary passwords in one fell swoop.


This attack can be prevented by salting the passwords when hashing them. Compare
the following code:


require 'digest/sha1'

$hashes = {}
$salts = {}

def hash(password, salt)
Digest::SHA1.hexdigest("--#{salt}--#{password}--")
end
Free download pdf