[UPHPU] Update on the security of md5 (for those who were at
mac at macnewbold.com
Mon Jan 24 17:11:46 MST 2005
Today at 2:39pm, Jeffrey Moss said:
> Well, the code you write may be pretty secure, but suppose you download a web
> script off the net like a bulletin board that was written by a group of
> people, some guy contributed some code that allows people to select something
> based on parameters passed into the script, so if you pass in this value as an
> example: "1'; select * from users" you get back the entire users table,
> passwords and all. This has happened countless times, your code may be
> succeptible to something like this, anywhere you use raw sql, so do this:
> "select * from users where login = ?" instead of doing this: "select * from
> users where login = '$login'".
Actually, SQL injection isn't a very big problem with PHP when you have
magic_quotes_gpc turned on in your php.ini, which is the default. It would
turn your "1'; select * from users" into "1\'; select * from users", which
is simply a string with an apostrophe in it.
The other catch is that for SQL injection to work in cases where you're
trying to get data back, the code has to be set up to be able to print out
the data you're trying to read. So either the code would need to be
indifferent about the field names, and print out the fields in a way
useful to you, or you'd need to write your injected query in a way that
renames the fields appropriately. Without having source code, this would
be somewhat difficult to do.
>> If someone get the "pass" value from the users table they will have the
>> salt as well as the hash. Then they would be able to perform similar
>> logic $exp_crypt = explode("$",$crypt);
>> $salt = $exp_crypt;
>> I guess my beef with the whole thing boils down to our efforts to
>> protect weak passwords. Salt will only help if it is stored or
>> calculated separately from the hash.
>> Jeff "my head is about to explode" Smith
>> Hrmm, I guess my last reply didn't go to the list. Sorry about that.
>> Anyway, salting prevents against dictionary attacks if the attacker has
>> the actual end hash.
To elaborate on Adam's (correct) response, the salt doesn't need to be
secret any more than the md5 hash needs to be secret.
1. MD5 hashes are vulnerable to brute force attacks, namely, an attacker
could try hashing strings until they find a matching hash. This takes a
very very long time for a good password, and not so long for a weak
2. MD5 hashes are also vulnerable to dictionary attacks, where they
_precompute_ a lot of hashes, and then just look up the matching hash in
their "dictionary" to find the string that can generate that hash.
3. Salted hashes prevent dictionary attacks, by increasing the size of the
dictionary that would be required to run an effective dictionary attack.
The old DES crypt() routines in unix/linux would add two chars (<=16bits
of entropy) as salt. Modern MD5 routines add 48 bits (8 chars) of salt,
making almost 3x10^14 possible salt values, making a dictionary attack
practically impossible, because you'd need about 300 trillion hashes of
_every_ string in your dictionary to be able to look up a hash with any
4. Salt _does_not_ prevent against brute force attacks, nor make them any
harder, unless the salt is secret. If the salt is secret, then it makes a
brute force attack 300 trillion times harder. But the salt cannot
effectively be kept secret any more than the hash itself can, because both
are needed to verify a password. So in general, salt is kept with the
If someone gets your hash with its salt, they can still run a brute force
attack on it, just as if it hadn't been salted at all. But what the salt
provides you is _time_. They can't spend bajillions of cycles ahead of
time building a dictionary, then steal your hash and use it immediately.
They've got to steal your hash and salt _first_, then try to brute force
it by testing lots of strings _with_that_particular_salt_, hoping to
stumble upon your password. MD5 is designed so that this type of brute
force attack takes a long time (as in many years, for a strong password).
So if your hash is stolen, or you suspect it may have been, all you need
to do is change your password before they crack it, and they'll never be
able to use the old hash.
A weak password can be cracked on a single modern CPU in a matter of days,
depending on how weak it is. That isn't because they can try all the
strings of less than 6 chars, it's because they have an intelligent way of
guessing the most likely things first, typically by using a word list, and
some transformations on it. See crack and/or cracklib for details... it's
an open source tool for doing just that. Good guys run it on their own
password file and hashes, to make people with weak passwords change them.
Good guys often will check new passwords against the algorithm to see if
the password they chose would be on the short list of things to try. Bad
guys run it on other people's hashes.
Most things in security are not your generic "silver bullet" solutions...
certain measures protect against certain things, while doing nothing to
protect against other attacks. To make good security, you need to know
your threat model. MD5 is collision resistant, making it strong against
brute force attacks, though not invincible, and quite vulnerable to
dictionary attacks (as www.passcracking.com demonstrates). Salted hashes
are resistant to dictionary attacs (one of the most effective ways of
running a brute force attack). When used together, they're at least as
good of a defense as the password you feed into them. Combine that with
all your measures to keep your hashes secret in the first place, and
you're pretty safe from password-guessing attacks.
Of course, password-guessing is only one way of attacking, so it's only
one of the many things you have to worry about to make a secure system...
Mac Newbold MNE - Mac Newbold Enterprises, LLC
mac at macnewbold.com http://www.macnewbold.com/
More information about the UPHPU