How To, and How Not to Hash Passwords
Lecture, Dr. Lawlor
How not to hash passwords: LM_hash
LMhash = concat(
Still, it could be worse:
- Use an obsolete cipher (DES)
- Remove entropy before hashing (uppercase all passwords)
- Limit password length by truncation (14 bytes)
- Hash the password in brute forceable chunks (7 bytes)
- Combine the per-chunk hashes by concatenating them. This
allows you to trivially extract each half.
- Don't use a salt/nonce, so the hash is a perfectly
deterministic function of the input, allowing attackers to look
up the hash in a Rainbow
- Hand out this hash over the network to anyone! As of
Windows Vista, this network hole is now plugged by
default. Hashed passwords are still stored in
although now that file is locked by the kernel, and encrypted.
One annoying thing about bad network protocols: they're almost
impossible to kill. The problem is that *every* client needs
to be upgraded before the server can stop using the old protocol
(even the ancient Windows 98 machine in the back, running the
- At least they used DES, which is still relatively
secure. They could have rolled their own encryption, which
would almost certainly have been worthless.
- Flipping the order of the DESencrypt parameters (encrypt
password using fixed key) would have allowed anybody to
DESdecrypt the exact password.
How to hash passwords well: HTTP
HA1 = MD5(username + realm + password);
HA2 = MD5(method + digestURI);
response = MD5(HA1 + nonce + HA2);
- The server can precompute HA1, and only store the hash for
each user, not the raw password.
- The server gets to choose a "nonce" (random number) to prevent
a bad client from just repeating the response of a good client
(a "replay attack").
It'd still be possible to improve this, though:
These improvements were implemented in RFC2617.
- If HA1 included a server_nonce, the server could protect
itself against stolen hashes.
- The client should get to choose a nonce, too.