Tech Monger

Programming, Web Development and Computer Science.

Skip to main content| Skip to information by topic

How to store passwords securely using Werkzeug

In this article we will learn how to implement secure user authentication system using python werkzeug. We will store secure passwords with salted hashes and later we will verify entered user password in plaintext against it's password hash to authenticate user.

Werkzeug is python library which contains lot of development and debugging tools for implementation of web application gateway interface(WSGI) applications. The good part is you can use this system not only for your web applications but also for standalone python applications like desktop apps, scripts, mobile apps and so on.

Install Werkzeug with pip

pip install werkzeug

Skip this step if you are using flask because flask will automatically install werkzeug as werkzeug is one of the dependency for flask.

Understanding Secure Passwords

Before we delve into the code it's good idea to zero in on what is secure password storage.

  • Passwords will not be stored as plaintext in database.
  • Password will be stored as hash which is irreversible to plaintext. (one way hash).
  • With given hash attacker cannot guess plaintext.
  • Each user password will be hashed with salt to mitigate rainbow table attacks; Just in case if database got compromised.

Werkzeug Security Functions

There are various security functions available in the werkzeug.security but we are interested in generate_password_hash and check_password_hash.

generate_password_hash

generate_password_hash takes plaintext password, hashing method and salt length as an input to produce hashed password. By default it produces salt string with length 8.

from werkzeug.security import generate_password_hash
print generate_password_hash("P1ain-text-user-passw@rd", "sha256")
sha256$lTsEjTVv$c794661e2c734903267fbc39205e53eca607f9ca2f85812c95020fe8afb3bc62

Note that output string contains hashing method, salt and hashed password concatenated with the $ (dolor). Store hashed string as it is in your database under column hashed_password.

check_password_hash

check_password_hash takes two inputs password hash and plaintext password and returns True if hash matches actual hash of plaintext password else returns False

from werkzeug.security import check_password_hash

print check_password_hash("sha256$lTsEjTVv$c794661e2c734903267fbc39205e53eca607f9ca2f85812c95020fe8afb3bc62", "P1ain-text-user-passw@rd")

>> True
from werkzeug.security import check_password_hash

print check_password_hash("sha256$lTsEjTVv$c794661e2c734903267fbc39205e53eca607f9ca2f85812c95020fe8afb3bc62", "wrong-passw@rd")

>> False

Conclusion

  • When you allow user to signup use generate_password_hash and store hashed version of password in database under column hashed_pwd.
  • Do not store plaintext password.
  • When you authenticate user via sign in use check_password_hash by passing already hashed password for user from database and input password (plaintext) to test veracity of password.
  • Tagged Under : Flask Python Web