I use generate_password_hash
from werkzeug.security
to hash and salt my passwords. I recently saw this article about SHA-1 collisions. werkzeug.security
uses SHA-1 and since it is not as safe any more I would like an alternative. How can I hash my passwords without relying on SHA-1?
from werkzeug.security import generate_password_hash
generate_password_hash(secret)
Werkzeug is a comprehensive WSGI web application library. It began as a simple collection of various utilities for WSGI applications and has become one of the most advanced WSGI utility libraries.
check_password_hash (pwhash, password)[source] check a password against a given salted and hashed password value. In order to support unsalted legacy passwords this method supports plain text passwords, md5 and sha1 hashes (both salted and unsalted). Returns True if the password matched, False otherwise.
The use of SHA-1 in generate_password_hash
is not vulnerable, as it is only used as an intermediate, iterated step in the PBKDF2 hash. See the discussion in chat.
when you're chaining zillions of hashes as in PBKDF2 the risk is indistinguishable from someone breaking a strong password by pure chance.
There was further discussion on the cryptography-dev mailing list.
You're correct that HMAC's security is still fine when used with SHA-1, HMAC-MD5 is even secure believe it or not.
generate_password_hash
takes a method
argument to customize how the hash is generated. The default is pbkdf2:sha1
. Pass a different derivation method for PBKDF2.
generate_password_hash(secret, method='pbkdf2:sha512')
You can also change the number of iterations from the default of 150,000 to a higher number, at the cost of a slower hash speed. pbkdf2:sha1:200000
.
You're probably okay with PBKDF2, as long as the hash and iterations are tuned well. Alternatively, use Passlib, which supports more hash methods than Werkzeug. See Passlib's recommended hashes for discussion on which hashes to use. This example shows how to use bcrypt with Passlib.
pip install passlib bcrypt
from passlib.context import CryptContext
crypt_context = CryptContext(schemes=['bcrypt_sha256'])
crypt_context.hash(secret)
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