Replace pbkdf2 with bcrypt#16071
Replace pbkdf2 with bcrypt#16071balloob merged 9 commits intohome-assistant:devfrom Eriner:feature-bcrypt
Conversation
There was a problem hiding this comment.
So one downside of using bcrypt is that it requires an external dependency. They are providing wheels for Windows, Mac and Linux, so that's good:
For Python 3.7 there are currently only wheels for Windows. Windows users have the most difficulty building stuff, so that's good.
Because it's part of the PYCA org, I think I would trust it to remain maintained.
There was a problem hiding this comment.
We'll need a migration path. We can only do the migration while a user is logging in. Verify with old pattern -> if ok, migrate to new salt.
|
Added upgrade path, though tests are failing because I'm a shitty python dev. From what I can tell in the upgrade test, I need to set the generated password in the underlying structure but I'm not sure how to do that from the test; asking someone here is faster than me spending time trying to figure it out. Also, there are probably issues with encoding/types somewhere. I'm doing my best but would appreciate some help with this one for the sake of time. |
|
Fixed the test. Also made a small change to the migration code. It's 👍 from me but let me know if you agree. |
|
Glad I wasn't too far off. Now that this is on the right track, give me another day or so of staring at it to make sure that I haven't made any silly mistakes. |
|
Added one extra test to make sure that incorrect legacy passwords still blow up. |
|
Can we plan to remove the upgrade path and legacy hashing after some period of time? Any unnecessary complexity in authentication and authorization logic makes me uncomfortable. |
|
Yeah, I would say in ~2 months |
bcrypt isn't inherently better than pbkdf2, but everything "just works" out of the box. * the hash verification routine now only computes one hash per call * a per-user salt is built into the hash as opposed to the current global salt * bcrypt.checkpw() is immune to timing attacks regardless of input * hash strength is a function of real time benchmarks and a "difficulty" level, meaning we won't have to ever update the iteration count
|
Going to make this part of 0.77. Because this change is forward compatible, but not backwards compatible, I don't want it to launch any later than 77, which will enable the auth system by default. |
|
Need add a note somewhere, if user rollback from 0.77 to prior verison, he need clean |
* Replace pbkdf2 with bcrypt bcrypt isn't inherently better than pbkdf2, but everything "just works" out of the box. * the hash verification routine now only computes one hash per call * a per-user salt is built into the hash as opposed to the current global salt * bcrypt.checkpw() is immune to timing attacks regardless of input * hash strength is a function of real time benchmarks and a "difficulty" level, meaning we won't have to ever update the iteration count * WIP: add hash upgrade mechanism * WIP: clarify decode issue * remove stale testing code * Fix test * Ensure incorrect legacy passwords fail * Add better invalid legacy password test * Lint * Run tests in async scope
|
Yes, LGTM. Thanks @balloob! |

Description:
bcrypt isn't inherently better than pbkdf2, but everything "just works"
out of the box.
global salt
"difficulty" level, meaning we won't have to ever update the iteration
count
Note that I haven't tested this code myself. Also, this won't be a clean upgrade for current "beta" users, not sure how that should be handled.
Example entry for
configuration.yaml(if applicable):Checklist:
tox. Your PR cannot be merged unless tests passIf user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
REQUIREMENTSvariable (example).requirements_all.txtby runningscript/gen_requirements_all.py..coveragerc.If the code does not interact with devices: