Here's a version that's much easier to read than the spec:
https://github.com/emerose/pbkdf2-ruby/blob/master/lib/pbkdf...
I should stop saying PBKDF2 and just go back to saying PBKDF.
I'd be happy to find out I'm wrong.
HASH.update(salt)
On each iteration as well? Then again, if things were this simple, someone would have already said "just do this", it would have been peer-reviewed and would have become widely used. Anyone know why this hasn't caught on yet in web frameworks like Django/Rails?When working with cryptography, "why not also add" is really dangerous, because some times you get less secure systems after doing so. And other times you get no benefits from doing so.
Assume you have a perfect cryptographic hash function H(X). No matter how many of N bits of X you change (0 < N <= len(X)), on average 50% of the bits of H(X) will change. So, let's consider the case of just H(salt || H(salt || password)) versus H(salt || H(password)).
Let A = H(salt||password), and let B = H(password). A and B are now, for all practical purposes, two different random integers. Each of which has the same entropy. This is because adding the salt should make no impact on the quality of these random numbers. It should now be fairly easy to see that there is no difference between H(salt||A) and H(salt||B), other than the fact that they produce different outputs.
This is all based on the assumption that the hash function is a perfect one -- however this assumption is reasonable for strong hash functions.
EDIT: also what Thomas said. It is in the standard that 1000 should be the minimum value. I would use higher based on the level of protection you want to give your users. Note that different hash functions have different costs so this will also impact the choice of X.
[Note: you should absolutely have a different salt for each password with this approach.]