4

Background:
We have an application with password authentication. We now need to raise the number of PBKDF2-iterations and this means that the login takes quite a bit longer than before. Therefore, instead of a spinning wheel animation, we would prefer a progress bar of some sort. We would then need some way of measuring the progress in order to show this data to the user, and the crypto library we're using does not provide this, just functions with input values and output.

Question:
What is a good way to track progress of a PBKDF2 calculation?

Our attempts:
We have a few different suggestions:

  • A - splitting the iteration count up across multiple smaller calculations with different salts and then combining the results with an xor or hash at the end.
  • B - running a small test calculation first, discard the results, and then running the real calculation afterwards.

Option A is better since we get a better progress estimate and we don't have to discard any calculations. Some had some worries however that doing it that way might have some security implications. Option B should have no security implications but requires some unnecessary work.

Edit:
We need to stick with PBKDF2 unfortunately due to compliance reasons and as I understand it we had customers asking for it to be in accordance with some public recommendations, which then resulted in a minimum number of iterations needed. In our testing we couldn't guarantee that the calculation is quick for all users so that's why a progress bar was suggested.

6
  • Which language and crypto library are you currently using?
    – Sjoerd
    Commented May 14 at 13:30
  • 6
    "We now need to raise the number of PBKDF2-iterations" -- says who for what reason? And what exactly did they say the number of iterations should be?
    – Ja1024
    Commented May 14 at 13:34
  • 3
    Regarding your edit: It’s probably a good idea to find out which exact document the recommendation comes from and what that document really says. Right now, this all sounds rather vague, and the recommended number obviously doesn’t work for you. If the authentication procedure by itself already overloads the available resources, then several parallel requests (by an attacker or legitimate users) will make the authentication services completely unusable. That’s certainly not acceptable, and it's not what any serious institution would recommend.
    – Ja1024
    Commented May 14 at 15:51
  • 6
    Why does the progress bar need to be precise? If it is just a UI feature, a good guess or a progress bar that gets slower the further it goes without ever reaching the end might be enough?
    – nvoigt
    Commented May 15 at 14:08
  • 1
    I'm not sure that this is a security question. Capturing the runtime of a function is a pure programming issue, not a security one.
    – schroeder
    Commented May 16 at 8:50

3 Answers 3

22

If your PBKDF2 calculations take so long that you need a progress bar, there's something seriously wrong. The calculations shouldn't take more than a few seconds, otherwise the number of iterations is far too high for the hardware. This is not only a usability problem, it also massively increases the risk of denial-of-service attacks against the authentication service.

PBKDF2 is generally a rather outdated algorithm which doesn't provide protection against brute-force attacks with modern GPUs and specialized hardware like ASICs. So instead of increasing the iterations to absurd levels, you should consider switching to a more modern algorithm like Argon2id.

If you absolutely must stick to PBKDF2, then you have to find reasonable settings. A common approach is to set a desired calculation time, e.g., 1 second. Start with a relatively low number of iterations and slowly increase it it until you've reached that time on the target hardware. If somebody or something mandates a minimum number of iterations, then take that into account, but again, this has to be within reasonable limits.

20
  • 4
    @PaŭloEbermann: Hashing should generally happen on the server side. You should know what your own hardware looks like and how well it performs.
    – Kevin
    Commented May 15 at 4:20
  • 1
    @Kevin That is fine for internal software, or Software as a Service. But if it is a Self Hosted software package the Developers will not know what the hardware is. They might (should) have minimum requirements for hardware but that may not be a) Mandatory; b) Reliably Enforced. This would then lead down "Make the system admin configure the hashing parameters" but the software should be as secure as is reasonable by default anyway since a lot of admins are not going to know how (or care) to tune them.
    – Justinw
    Commented May 15 at 8:21
  • 2
    @Justinw: The OP talked about tablets doing the calculations. Those are client devices, not servers, so Kevin is correct. In any case, PBKDF2 isn't meant to completely exhaust the hardware for a longer period of time. Either there's a misunderstanding, or the OP must set up dynamically calculated iterations based on the detected hardware + a configuration option.
    – Ja1024
    Commented May 15 at 10:44
  • 3
    "The calculations shouldn't take more than a few seconds" - Actually, I'd argue password hashing should take well below a second for most users. Compromising usability for a minute gain in security is rarely worth it.
    – marcelm
    Commented May 15 at 11:37
  • 7
    "The calculations shouldn't take more than a few seconds, [if they] take so long that you need a progress bar, there's something seriously wrong." - if you're measuring time in seconds already, not milliseconds, usability is already impacted. It might warrant a progress bar if there's only a "few seconds".
    – Bergi
    Commented May 15 at 12:30
9

Messing around with cryptographic code just to get a more accurate progress bar to display to users on a login seems like a very dangerous idea for limited benefits. It's very easy to introduce subtle bugs into crypto code unless you really know what you're doing - and even if you do you then make it much harder to maintain going forward as you're no longer using a standard library.

A much simpler solution would be just to run some benchmarks under various conditions to see roughly how long the PBKDF2 operation takes, and then just fudge it with a progress bar that takes 2 seconds (or however long). If it's just a user-facing progress bar that'll be shown for a few seconds (at most) then it doesn't have to be perfectly accurate.

But as others have said, if your hash calculation is taking more than a few seconds then it sounds like your PBKFD2 iteration count is probably quite a bit higher than it should be - which makes it a lot easier for an attacker to DoS your server by making large numbers of login attempts.

And you'd get far more better security from using a better hashing algorithm (such as Argon2id) tuned to take 1 second that you would from PBKDF2 taking 10 seconds - so unless you really need to be using PBKDF2 for compliance reasons, consider moving away.

1
  • You don't even need a benchmark. Remember how long it took last time and use that. Extra credit for averaging the last few runs. It's generally accurate after the first use, which nobody will remember anyway. Many systems use this technique.
    – user71659
    Commented May 16 at 21:42
0

PBKDF2 does a number of iterations. The correct way to track progress is to add some code to the loop that reports the current iteration number.

If your current crypto implementation does not support this, perhaps you could implement the loop yourself. However, implementing your own crypto is risky and could be slow.

A - splitting the iteration count up across multiple smaller calculations with different salts and then combining the results with an xor or hash at the end.

This is perfectly parallelizable, which reduces the security of the password hash.

5
  • 5
    Having to track the progress of PBKDF2 in the UI sounds absolutely bizarre. Even in sensitive contexts (where PBKDF2 isn't the best choice anyway), the calculations shouldn't take more than maybe 1 or 2 seconds. I'm fairly sure the OP or whoever told them to increase the iterations just misunderstood something.
    – Ja1024
    Commented May 14 at 13:39
  • @Ja1024 Even "maybe 1 or 2 seconds" is long enough that a progress indicator may make the UI feel more responsive. Commented May 16 at 13:28
  • IMO, given the OP's stated requirements, this is the answer: either find a crypto library that can report PBKDF2 progress or implement PBKDF2 yourself (on top of a secure cryptographic hash implementation, of course). Ideally you'd also get a crypto expert to review your implementation, but for a "high-level" algorithm like PBKDF2 that's IMO not strictly necessary. Just check that your implementation gives the same output (for the same inputs and parameters) as other known good PBKDF2 implementations and is not significantly slower than they are. Commented May 16 at 13:28
  • 3
    @IlmariKaronen: The OP's "requirements" are that some customer said something about some document making some recommendation. Based on that you suggest rolling your own PBKDF2 implementation and then either paying a professional cryptographer for a review or only doing basic tests, just to make the UI feel more responsive? Sorry, but this is absurd. First off, "1 or 2 seconds" was meant as a rough upper limit. If you're afraid that users get irritated by this delay, then implement a spinning wheel. In reality, I'm pretty sure users don't care, because they don't log in and out all the time.
    – Ja1024
    Commented May 16 at 17:15
  • @Ja1024 As much as I'm against rolling your own crypto, there's really very little (read: zero) risk in implementing PBKDF2 yourself. It's just calling a hash in a loop. Ten lines of code or so, and no real cryptography involved. (As something that runs client-side, side-channels aren't a concern.)
    – TooTea
    Commented May 17 at 9:21

You must log in to answer this question.

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