[Haskell-cafe] Password hashing

Daniel B. Giffin daniel at mybuttocks.com
Thu Oct 30 15:30:46 EDT 2008

to expand on this:

Bulat Ziganshin wrote:
> 1) without salt, it's not serious - easily breaked by dictionary
> attack

and this:

Thomas Schilling wrote:
> In general, it is recommended that password hash functions are
> comparatively *slow* in order to make offline attacks harder.  You can
> somewhat emulate this by running the hashing function multiple times.
> And, of course, salting should always be done.

(and leaving aside vulnerabilities in MD5 itself ...)

without a salt, the concern is that someone has a list of the
MD5-hashes of a few million likely passwords (such things are
available on the internet, and also straightforward to compute
yourself).  an attacker in possession of your hashed-passwords file
may then look up each hash in his list; if one matches, he knows the
plaintext password.  if everyone used this simple scheme, the same
dictionary (mapping hashes back to plaintext) could be leveraged to
attack anyone's password file.

if you append some random salt material to every password before
hashing it, an attacker will in essense need a separate dictionary for
every salt value.  in practice (because there are too many such
dictionaries to bother pre-computing them),  to attack a particular
salted-and-hashed password, he will just start hashing all his
favorite passwords along with the associated salt until he gets lucky
and one matches.  (or perhaps he will do this in parallel over the
whole file, not caring which account is broken.)

in order to make this take as long as possible, you want the hashing
function to be slow to compute.  if it takes you a second or two to
compute the hash when somebody logs in, fine -- this means the bad guy
will have to spend over a week trying a million passwords against one
of your accounts (unless he has a faster algorithm or better hardware
than you).

the nice thing about bcrypt, then, is that it has configurable cost.
you pick whatever cost you can tolerate now, and then as new passwords
are hashed over the years you can keep increasing the cost in order to
keep up with the faster hardware that is available (to you and to
attackers).  (storing the cost along with each hash allows a single
password file with heterogenous hash-costs.)

i might try my hand at a haskell-native module if i find the time, but
for now using FFI to access bcrypt (or just forking a child process to
compute it) is probably the safest bet.

A Future-Adaptable Password Scheme

(hm, bcrypt implementations appear to be hard to find outside of
OpenBSD, and also there is the confusing existence of a "bcrypt"
utility that just does normal blowfish encryption.  anybody know of a
packaged linux library or utility that does the eksblowfish hash?)

More information about the Haskell-Cafe mailing list