I have to migrate my flask Users to django. In flask I generated the password with the werkzeug lib like:
generate_password_hash(value, method='sha256')
In the django import I save the password:
u.password = hashed_pw
now the password is in the database like:
'sha256$VSvtvATP$2c87cf...'
now django can't verify my password. How can I convert the password so that django can handle it?
Django uses a different password hashing algorithm by default, namely PBKDF2 with SHA-256. The only way you could move the existing hashes over to Django would be to tell it to use a different hasher. A plain SHA-256-Hasher isn't built-in, so you'd have to write your own.
However, I would consider not doing that and providing a migration path for your existing users, since PBKDF2-sha256 is considered more secure:
Store these hashes in an additional field on your user, and prompt them to change their password on their first login (then throw away the old hash and only save their password hashed the Django way). You could even do this transparently to your users (i.e. on first login, after checking the hash matches with the old hash from Flask, generate a new hash based on the same password (that you have at this point in time) and store it, then throw the old hash away.
flask and django use hashlib.pbkdf2_hmac to generate password hash. the difference is the format and encoding. so possible to translate the password hash from one format to another transparently. (I wonder why not uniform and decrease the friction)
def trans_hash(str):
"""from flask to django"""
[alg, _hash_alg, rest] = str.split(':')
[iteration, salt, hashed] = rest.split('$')
# in flask hex() formated, so decode using b16decode
# https://github.com/pallets/werkzeug/blob/main/src/werkzeug/security.py#L162
raw_hash = base64.b16decode(hashed.strip().encode('ascii').upper())
# in django, use b64encode, https://github.com/django/django/blob/ca9872905559026af82000e46cde6f7dedc897b6/django/contrib/auth/hashers.py#L276
hashed = base64.b64encode(raw_hash).decode('ascii').strip()
rest = '$'.join([iteration, salt, hashed] )
return f"{alg}_{_hash_alg}${rest}"
a password hash in flask:
pbkdf2:sha256:150000$zwBNBm5i$be85b2739ab81c94ea2596fe79c0f6e7d211561f5ea1525c5620e817ef3ea82b
will translate to (django)
pbkdf2_sha256$150000$zwBNBm5i$voWyc5q4HJTqJZb+ecD259IRVh9eoVJcViDoF+8+qCs=
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With