Skip to content

Password Hashing (Werkzeug)

Never store plaintext passwords.

If your database leaks and passwords are stored as plaintext, every user account is compromised.

Hashing vs encryption

  • Hashing: one-way (you can’t recover original password)
  • Encryption: reversible (not what you want for passwords)

Passwords should be stored as:

  • salted, slow hashes

Werkzeug helpers

Flask uses Werkzeug, which provides:

  • generate_password_hash()generate_password_hash()
  • check_password_hash()check_password_hash()

Example:

from werkzeug.security import generate_password_hash, check_password_hash
 
hashed = generate_password_hash("my_password")
 
assert check_password_hash(hashed, "my_password") is True
assert check_password_hash(hashed, "wrong") is False
from werkzeug.security import generate_password_hash, check_password_hash
 
hashed = generate_password_hash("my_password")
 
assert check_password_hash(hashed, "my_password") is True
assert check_password_hash(hashed, "wrong") is False

Store in DB

Typically your user model has:

  • password_hashpassword_hash column

And you never store the raw password.

Common pitfalls

  • Comparing raw passwords in code
  • Using fast hashes like MD5/SHA1 for passwords (too fast)
  • Logging passwords in debug logs

Werkzeug’s defaults are safe for most projects.

If this helped you, consider buying me a coffee ☕

Buy me a coffee

Was this page helpful?

Let us know how we did