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?

3 Answers 3


The sauce is not an extra hoop. The attacker doesn't gain any benefit from knowing the sauce in advance. The salt prevents him from making useful precomputations anyway.

The optimal iteration count is determined from a compromise between your available computing power and the computing power available to a typical attacker. Sure, it's hard to quantify it precisely, but nonetheless randomization can only make the resulting value less optimal.

If the attacker wants to get a foothold into the organization and doesn't care much which account he breaches, the accounts with the lowest sauce are likely to fall first (though password complexity will have more influence). The randomization hurts more than it helps in this scenario, since it makes the weakest link weaker without a commensurate compensation by gained processing time.

Your random sauce is extra complexity, even if i's only a little bit. Complexity is the enemy of security, it's one more thing you might accidentally get wrong (e.g. a too-low minimal sauce).

In conclusion, I recommend a fixed iteration count, changing from time to time as processors get more powerful.

  • All 3 answers were fantastic and complemented each other, but I've accepted this one from Gilles based on the note about complexity being the enemy of security.
    – Scott P
    Commented Jun 13, 2013 at 16:37

In the scenario:

  • I have your passwords, hashed
  • You use salt, in the correct way, so there's no use for my pre-computed rainbow tables
  • I'll have to brute-force using the salt that I already have, and pepper, and sauce...

Well, first of all, I just have to bring my own salad, because the condiments are given by you :)

Secondly, I'll have the number of iterations, since you have it like the salt, that is not that secret.

But even if I don't have it, I'll have to compute all those iterations. If I know that they'll be from 16,000 to 32,000, I'll simply test my result after the 16,000th. By your scheme, instead of having to iterate up to 32,000, perhaps I'm lucky and get the result before that. Don't know if testing it will take more computing power than calculating every new iteration, so perhaps it worths to try...

And, finally, rainbow tables are a way to optimize the pre-computed values, it's not a simply lookup table.


You want your iteration count to be as high as you can tolerate given your system's performance and expected compute overhead that this adds to your authorisation process, and definitely not something that's adjustable in a per user manner. Besides, you will have to keep this value somewhere, meaning it can't be considered a secret, so you're not really slowing down any more or even stopping the would-be attacker, you're merely providing for a chance he might finish his task of brute-forcing individual hashes faster, than with the maximum iteration count you can live with.

Oh, and why can't your iteration count be kept a secret? Well, simple. Even if you used some really inventive scheme of protecting that value, you'll be later using it, and different iteration values will result in different compute overhead - something an attacker can check against with what are called timing attacks. An attacker could use even your live system to determine with relatively good precision the iteration count used for each account.

  • 1
    Actually, keeping the iteration count a secret can work: for online attacks, keep idle for the remaining expected length of calculation (and online attacks get very few tries anyway, so there's very little timing information to be had in the first place); for offline attacks, the attacker doesn't get to time the legitimate servers. But it's not really useful, since the attacker only has to iterate to the maximum as well. Commented Jun 7, 2013 at 20:27
  • @Gilles - Well yes, I guess it could be made to sleep for the remaining duration and make all of them appear to take same amount of time. It's still nothing gained by doing it so though, you just end up sleeping while your time would be better spent (security-wise) working. Anyway, if timing attacks aren't considered at all, it's still an added bonus to the attacker, so I'm leaving it in the answer as a reminder. Thanks for your comment! ;)
    – TildalWave
    Commented Jun 7, 2013 at 21:00
  • Realistically, wouldn't an attacker know the number of iterations already even if it wasn't stored as sauce? I'm assuming that if they've got into the DB, they've probably also found a way onto the web server and outright copied the file that does the processing in the first place.
    – Scott P
    Commented Jun 7, 2013 at 21:01
  • 1
    @ScottPritchard - Yes, that's the proper assumption. Technically, it's still possible an attacker obtained DB only of course, say by getting his hands on a misplaced backup copy or similar. But you should always anticipate the worst and the attacker has gained access to everything he needs to reverse all your processes, except to somehow extract passwords out of their hashes. Hopefully (because we really can't know for sure) the hashing function used is a true one-way function, and the attacker can only test it against all possible values.
    – TildalWave
    Commented Jun 7, 2013 at 21:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .