I'm working on a PHP authentication and registration system following the standard salt+password = 'auth hash' and using the plaintext/unencrypted username as the lookup field on the initial query. For the intent of this question, let's assume I'm using a global pepper as well (I'll likely add one prior to finish, so let's pretend I've already done that).
Something just struck me as a perhaps interesting concept. I realize they say "don't reinvent the wheel when it comes to security", but I was considering allowing a 'user specified' number of iterations for PBKDF2.
Now, I don't mean that the user has control over the number of iterations, but rather, a random number between X and Y is generated at runtime and then that value is stored, in plaintext, as a separate field in the database in the same way that you'd store the salt. I understand that the algorithm is already viewed as being extremely secure while being simple to implement, but I figure that an extra 'layer' would make it even more difficult for an attacker to work against.
For the sake of simplicity (and continuity with using foodstuffs), let's call the random iteration count 'sauce'. As an example;
- Pepper is already in DB and is retrieved to a variable
- User registers with username and password
- Salt is generated
- Sauce is generated, and must be between 16000 and 32000 iterations (theoretical numbers)
- Hash is generated from salt+password+pepper+sauce
- Username, hash, salt and sauce are stored in the DB
Since 'sauce' is stored as plain text, your algorithm itself would be adaptive based around what's stored in the database (just as with salt), and even more to the point, picking a number between X and Y is generally quite fast.
Again, I'm not concerned that an attacker could break a SHA512 hashed 512-bit length output key that's gone through 32000 (example number) iterations and has a salt and pepper within a reasonable amount of time, and they certainly couldn't generate a rainbow table against it. I'm more interested in the prospect that we could expand the design further, relatively easily, having very little additional overheads on the 'defenders' side, but adding more overheads to the attackers side, potentially deterring them completely, and without needing to adapt the hashing algorithm itself.
You set your own minimum and maximum iteration counts within range of what your environment can handle and thus you still maintain significant control over the relative security of the system, and you never allow your end users to specify their own value (for performance reasons, and for the reason they'll likely select something memorable completely nullifying your extra step, and for making for a nice UX). In environments where security is of paramount importance, surely having these extra little steps in the way would work in the benefit of the defenders.
Would having this extra level not provide yet another hoop for an attacker to jump through? Thoughts?