> bcrypt gets you a future-hardened algorithm that can be adjusted in responses to gains in computing power.
How would I be able to change the cost factor overtime? I don't store my user's passwords. Should I just re-bcrypt the bcrypted password using a higher cost and in my login_verify code, take that into account? Or is there something else you can do overtime to raise the cost factor?
One system I built stores the workfactor used to bcrypt the current password un the user table, and allows me to increase the "system workfactor". Every time someone successfully logs in with a lower-than-current-workfactor password hash, it recomputes a new bcrypted hash using the currently known successful login password and updates the users credentials. It means if my user table is ever exposed, all frequently used accounts have up-to-date workfactors for their password hashes, and the "relatively weaker" hashes are for infrequently used (or, in this particualar case, expired subscriptions).
EDIT: I've also recommended using a random salt for each password too, but this is only a layer of security if you're code is not also stolen, then it is simply a slight additional "slow factor"
You could up the iteration however much is needed (say, 1000, 10,000).
It's poor security countermeasure, but it was a specific scenario :) The general idea is to combine salting and iteration to produce a poor mans slow hash.
(which works great for software you're distributing for use on random shared architecture a la wordpress - just to give an example)
Use Bcrypt where you can.
That's the crux of the problem. Hashes that are good for fingerprinting files (MD5, SHA-n) aren't good for keeping passwords secure, because they need to be fast. Your idea seems fine, but you're forgetting the "first rule of implementing crypto primitives": don't do it! (http://www.letsyouandhimfight.com/2010/07/14/cl-bcrypt-a-fir...)
First off; it is not a primitive, but a protocol, it is still a bad idea to design those yourself. But they are not; they are getting the advice of an expert.
Secondly; this is in a specific scenario where you are left only with the fast digests (shockingly, this is still a common situation). Introducing an "artificial" slow factor is accepted practice.
Thirdly; this is definitely not my idea. The iteration suggestion was from tptacek who months ago answered a similar question to this with something along the lines of "if you must insist on using fast hashing for gods sake iterate it a number of times" (I can't find the quote off hand, it was some time ago, but I entirely agree). The rotating random salt is an old old idea.
It's very easy to recite the mantra "always use bcrypt, follow the first rule of crypto, digests are evil", but it's even harder to use that knowledge in practice, I find. :)
You can introduce slowing factors like seed values and iterations (bcrypt uses both) but they're a bad idea if you're doing it yourself. For example, your initial estimate of 50 iterations is at least a couple of orders of magnitude out. How many is safe? 10,000? 100,000?
BTW, I'd be interested to know exactly what this mythical situation is where you're handling user accounts, but don't have access to one of the existing bycrypt implementations (C, Ruby, Python, PHP) and can't compile your own.
However. Mythical situation? Try a good portion of shared PHP hosting; why do you think the most popular software in the world (i.e. stuff like Wordpress) still supports MD5/Sha hashing?
I realise this is not a problem you may have come across before; but don't imagine it does not exist :)
But really - it's just another reason not to use PHP, and not to have a crappy webhost. You could probably say much the same things about backups, app security, bad UI or design. But for most people, don't do that is apparently not a good enough answer.
Update: Just looking into how Django stores passwords, and it does much the same thing (although it falls back to SHA-1, rather than MD5). There was a push to use bcrypt a while back, but it got marked wontfix, due to "backwards compatibility issues". Sigh.
the search results from google are all added code, but php supports it natively: http://ca.php.net/manual/en/function.crypt.php
Edit: crypt -> bcrypt, stupid iPad autocorrect