The solution to this is to add a small chunk of random data — called a salt — to the password before it‘s hashed: hash(salt + p) #=> The salt is then stored along with the hash in the database, and used to check potentially valid passwords: =? hash(salt + just_entered_password)bcrypt-ruby automatically handles the storage and generation of these salts for you.Adding a salt means that an attacker has to have a gigantic database for each unique salt — for a salt made of 4 letters, that‘s 456,976 different databases. Pretty much no one has that much storage space, so attackers try a different, slower method — throw a list of potential passwords at each individual password: hash(salt + "aadvark") =?
hash(salt + "abacus") =?
etc.This is much slower than the big database approach, but most hash algorithms are pretty quick — and therein lies the problem. Hash algorithms aren‘t usually designed to be slow, they‘re designed to turn gigabytes of data into secure fingerprints as quickly as possible. bcrypt(), though, is designed to be computationally expensive: Ten thousand iterations:
user system total real
md5 0.070000 0.000000 0.070000 ( 0.070415)
bcrypt 22.230000 0.080000 22.310000 ( 22.493822)If an attacker was using Ruby to check each password, they could check ~140,000 passwords a second with MD5 but only ~450 passwords a second with bcrypt().
Názor byl 1× upraven, naposled 23. 08. 2012 03:47