4
$\begingroup$

Let's suppose I have a bunch of PBKDF2 hashes in a database. For the sake of keeping this simple, let's say I've used 10 iterations. A few years later I decide to upgrade to 20 iterations. I want to upgrade all hashes in one go so I rehash the old hashes instead of waiting for all users to log in. Do I use 20 or 10 iterations?

Basically, what I'm asking is this:

  • pbkdf2(20, password) == pbkdf2(20, pbkdf2(10, password))
  • pbkdf2(20, password) == pbkdf2(10, pbkdf2(10, password))

By == I mean equivalent in terms of security.

Which of the two is true?

$\endgroup$
  • $\begingroup$ I hope that this value of 10 is for demonstration purposes, right? $\endgroup$ – Maarten Bodewes Oct 17 '17 at 11:19
  • $\begingroup$ @MaartenBodewes Yes, I wanted to keep the question as simple as possible. That's why I've omitted the salts as well. (And thanks for your answer!) $\endgroup$ – Lukas Oct 17 '17 at 11:39
  • $\begingroup$ OT here on Cryptography but what I'd recommend if this were Information Security: Don't roll your own password management code! Use an established library instead! This library will (or at least should) be able to update stored password hashes on-the-fly whenever a user enters their password for the first time after a password hash policy change like this one. Such libraries exist for all major languages that are relevant in back-end web development. Some are geared towards specific web development frameworks or even directly endorsed by them. $\endgroup$ – David Foerster Oct 17 '17 at 15:21
4
$\begingroup$

PBKDF2 consists of a chain of one way functions. The one way functions are dependent on each others output and this output is computationally unique. That means that there are no shortcuts of creating a specific outcome.

So yes, you can chain the PBKDF2 functions that way. However, it won't be binary compatible with just using PBKDF2(20, password) as the concatenation of the steps that make up PBKDF2 will be different for both, even if you re-use the same salt.

Reusing the salt won't lead to problems, as the output of the previous PBKDF2 is randomized, so it will be different from any other password / output of the first stage.


Notes:

  • PBKDF2 directly uses the number of iterations, i.e. the work factor will increase linearly. Unfortunately computer processing power doesn't, it seems to continue to increase faster than that.
  • It may be a good idea to store some kind of version number with the PBKDF-2 hash so it is possible to distinguish between different forms of hashing (such as single PBKDF2 or extended PBKDF2 use as described.
  • TL;DR, option 2 is correct - yes iterations do stack.
$\endgroup$
  • $\begingroup$ What you're trying to say with your first note is that in practice you wouldn't want to double the iterations but rather use something like (let's say we've used 2^17 iterations to begin with) 2^18-2^17 iterations when rehashing to upgrade to 2^18 iterations, right? $\endgroup$ – Lukas Oct 17 '17 at 12:00
  • $\begingroup$ @Lukas don't attempt to rehash the passwords in your database to upgrade their security - instead, re-hash the passwords on next login with the higher work factor. $\endgroup$ – Riking Oct 17 '17 at 17:31
  • $\begingroup$ Right thats what I was trying to say. And yes, upgrading on the next login can also work, but I'm not going to comment on that because it also has drawbacks. $\endgroup$ – Maarten Bodewes Oct 17 '17 at 17:35
  • $\begingroup$ @Riking Well yeah, that's the easy part. I'm trying to figure out what to do with accounts of paying customers who only log in every 2 years or so (if at all) and inactive accounts. $\endgroup$ – Lukas Oct 17 '17 at 18:04
  • $\begingroup$ I strongly disagree with your TL;DR since as you say yourself it is not binary compatible and the result is no longer PBKDF2. $\endgroup$ – Meir Maor Oct 17 '17 at 20:20
3
$\begingroup$

Each iteration of PBKDF2 mixes in not only the previous iteration but also the original password and salt. This is a good security property though not crucial IMHO it prevents converging to fewer possible values after many iterations. Because of this behaviour we can not construct a higher iteration count hash from a lower one without the original password. We could a different KDF which only repeatedly hashes the same output or possibly mixes in the known salt which would allow such rehashing without password without sacrificing much security for reasonable iteration counts. This of course wouldn't be PBKDF2.

$\endgroup$
1
$\begingroup$

You can achieve this by:

  1. performing pbkdf2(10, existingHash) on all existing hashes and overwriting the existingHash

  2. for new passwords, store: hash = pbkdf2(10, pbkdf2(10, password))

  3. for all future verification: valid = hash == pbkdf2(10, pbkdf2(10, password)) ? true : false

$\endgroup$
  • $\begingroup$ According to Maarten, 1) and 2) would result in pbkdf2(30, password). I wanted pbkdf2(20, password). $\endgroup$ – Lukas Oct 17 '17 at 9:24
  • $\begingroup$ @Lukas That's true. I've updated my answer. $\endgroup$ – hunter Oct 17 '17 at 9:27
  • $\begingroup$ Also hash == pbkdf2(10, pbkdf2(10, password)) ? true : false is as redundant as true ? true : false, but that's beside the point. $\endgroup$ – Cthulhu Oct 17 '17 at 14:35
  • $\begingroup$ @Cthulhu it's verbose pseudocode written for the sake of clarity. It has other shortcomings, but they would also be beside the point. $\endgroup$ – hunter Oct 17 '17 at 14:52
0
$\begingroup$

While there are some schemes to rehash secrets (not in a purely compatible way for PBKD2) you should be aware that actualling hashing new secrets/passwords is better, so requiring a re-enter of secrets which are too weakly protects (like every 1-5 years) should not be dismissed.

Check out Mozilla’s solution to rehashing which uses PBKDF2 only as a beginning, such an approach is IMHO pretty sound: https://blog.mozilla.org/services/2014/04/30/firefox-syncs-new-security-model/

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.