Is hashing a password twice before storage any more or less secure than just hashing it once?
What I\'m talking about is doing this:
$hashed_password
I'm going to go out on a limb and say it's more secure in certain circumstances... don't downvote me yet though!
From a mathematical / cryptographical point of view, it's less secure, for reasons that I'm sure someone else will give you a clearer explanation of than I could.
However, there exist large databases of MD5 hashes, which are more likely to contain the "password" text than the MD5 of it. So by double-hashing you're reducing the effectiveness of those databases.
Of course, if you use a salt then this advantage (disadvantage?) goes away.
The concern about reducing the search space is mathematically correct, although the search space remains large enough that for all practical purposes (assuming you use salts), at 2^128. However, since we are talking about passwords, the number of possible 16-character strings (alphanumeric, caps matter, a few symbols thrown in) is roughly 2^98, according to my back-of-the-envelope calculations. So the perceived decrease in the search space is not really relevant.
Aside from that, there really is no difference, cryptographically speaking.
Although there is a crypto primitive called a "hash chain" -- a technique that allows you to do some cool tricks, like disclosing a signature key after it's been used, without sacrificing the integrity of the system -- given minimal time synchronization, this allows you to cleanly sidestep the problem of initial key distribution. Basically, you precompute a large set of hashes of hashes - h(h(h(h....(h(k))...))) , use the nth value to sign, after a set interval, you send out the key, and sign it using key (n-1). The recepients can now verify that you sent all the previous messages, and no one can fake your signature since the time period for which it is valid has passed.
Re-hashing hundreds of thousands of times like Bill suggests is just a waste of your cpu.. use a longer key if you are concerned about people breaking 128 bits.
Double hashing is ugly because it's more than likely an attacker has built a table to come up with most hashes. Better is to salt your hashes, and mix hashes together. There are also new schemas to "sign" hashes (basically salting), but in a more secure manner.
Yes, re-hashing reduces the search space, but no, it doesn't matter - the effective reduction is insignificant.
Re-hashing increases the time it takes to brute-force, but doing so only twice is also suboptimal.
What you really want is to hash the password with PBKDF2 - a proven method of using a secure hash with salt and iterations. Check out this SO response.
EDIT: I almost forgot - DON'T USE MD5!!!! Use a modern cryptographic hash such as the SHA-2 family (SHA-256, SHA-384, and SHA-512).
Personally I wouldn't bother with multiple hashses, but I'd make sure to also hash the UserName (or another User ID field) as well as the password so two users with the same password won't end up with the same hash. Also I'd probably throw some other constant string into the input string too for good measure.
$hashed_password = md5( "xxx" + "|" + user_name + "|" + plaintext_password);
In general, it provides no additional security to double hash or double encrypt something. If you can break the hash once, you can break it again. It usually doesn't hurt security to do this, though.
In your example of using MD5, as you probably know there are some collision issues. "Double Hashing" doesn't really help protect against this, since the same collisions will still result in the same first hash, which you can then MD5 again to get the second hash.
This does protect against dictionary attacks, like those "reverse MD5-databases", but so does salting.
On a tangent, Double encrypting something doesn't provide any additional security because all it does is result in a different key which is a combination of the two keys actually used. So the effort to find the "key" is not doubled because two keys do not actually need to be found. This isn't true for hashing, because the result of the hash is not usually the same length as the original input.