1
$\begingroup$

I want to debug bcrypt rounds with a static salt using this python lib

import bcrypt
salt = bcrypt.gensalt(14)
password = b"foo"
foo_1_round = bcrypt.kdf(password, salt, desired_key_bytes=10, rounds=1)
foo_2_rounds_manually = bcrypt.kdf(foo_1_round, salt, desired_key_bytes=10, rounds=1)

foo_2_rounds = bcrypt.kdf(password, salt, desired_key_bytes=10, rounds=2)

I expected to see equal foo_2_rounds and foo_2_rounds_manually

$\endgroup$
1
  • $\begingroup$ Please note that crossposting is not allowed. $\endgroup$
    – Maarten Bodewes
    Sep 24 at 19:48

2 Answers 2

3
$\begingroup$

Your expectation is incorrect. The output isn't just the intermediate state that could be used to continue processing. It's a specifically-formatted string according to https://en.wikipedia.org/wiki/Bcrypt. From a quick glance, continuing a calculation from an intermediate output should be possible, but you would need to parse the output and reverse the encoding instead of using it directly. And even then the outputs won't match exactly because the cost is embedded in the final result.

$\endgroup$
3
$\begingroup$

You can't calculate a bcrypt hash from a bcrypt hash with a lower cost factor. Few password hashing algorithm allow a cost factor increase without knowing the password, and bcrypt isn't one of them. Even for the algorithms that support a work factor increase, this isn't just passing the lower-cost result back into the input: it's a distinct algorithm.

The cost factor of password hashing algorithms is often called “iterations”, because for classic algorithms it's an iteration count. But for modern algorithms, the cost factor(s) often have more impact than a loop count. For bcrypt, the cost factor is used for the Blowfish key setup, which has a loop with $2^{\textrm{cost}}$ iterations. The hash is not the output of this loop: the output of this loop is a key and the hash is the encryption of a fixed text with this key. With a higher cost factor, the key is different and so the final result is completely unrelated.

$\endgroup$
2
  • $\begingroup$ Thinking about this: if the old hash could be an intermediate result and you would update to a higher iteration count then loosing the old hash value would let an attacker have a shortcut in determining the input password. Most of the time the hash gets updated together with a user action / password change. $\endgroup$
    – Maarten Bodewes
    Sep 22 at 23:35
  • 2
    $\begingroup$ @MaartenBodewes I don't understand your comment. I think you're arguing that a password hash that allows upgrading without knowing the password is broken, but I don't get it. If the old hash leaks, and the server upgrades the hash, and the user doesn't change the password, then the attacker has an easier time compared to the scenario where the old hash doesn't leak. Um, yes, ok, so what? It doesn't make a difference whether the hash can be upgraded without knowing the password. $\endgroup$ Sep 23 at 8:22

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