Even then, the passwords should be
symmetrically encrypted with a shared secret, to provide defense in depth.
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 protects
them from rainbow attacks.
Salting is 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 a rainbow attack. An attacker can
precompute rainbow tables by running every word in a dictionary through the hash
function.
Pages:
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200