When you have user accounts and you give them passwords you really don't want to store them in the database unhashed. However just hashing the passwords is barely more secure because of Rainbow table attacks. What you want to do is to salt the passwords which means that instead of just hashing the password you hash the password + a salt. And you also don't just want to concatenate them but use HMAC. And because that's common and easy to make wrong, Werkzeug provides a helper for that which also generates a hash for you.
Here is how it works. The following example assumes that you use some class for your user object:
from werkzeug.security import generate_password_hash, \
check_password_hash
class User(object):
def __init__(self, username, password):
self.username = username
self.set_password(password)
def set_password(self, password):
self.pw_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.pw_hash, password)
And here is how it works:
>>> me = User('John Doe', 'default')
>>> me.pw_hash
'sha1$Z9wtkQam$7e6e814998ab3de2b63401a58063c79d92865d79'
>>> me.check_password('default')
True
>>> me.check_password('defaultx')
False
This snippet by Armin Ronacher can be used freely for anything you like. Consider it public domain.
Comments
Typo? by Sean Lynch on 2011-07-12 @ 02:23
In the User example, I believe the last line should be: "return check_password_hash(self.pw_hash, password)" instead of "return check_password(self.pw_hash, password)"
Length? by Joe Esposito on 2011-07-25 @ 03:00
What's the resulting string length? Is it the same length as the plaintext? Smaller?
I'd like to know what to make the string size of the password_hash database column.
Length? by Joe Esposito on 2011-07-25 @ 03:05
Asked too soon, found the answer. If using SHA-1, the digest size is 160.
http://en.wikipedia.org/wiki/SHA-1
Typo? Yes. by Orphée Lafond-Lummis on 2011-10-15 @ 14:45
You spotted it. The check_password should indeed be check_password_hash.
Reference: http://werkzeug.pocoo.org/docs/utils/#module-werkzeug.security
Still best practice? by Alex Chamberlain on 2012-10-26 @ 13:37
There seem to be a lot of articles about that say this is a bad idea. For example,
http://security.stackexchange.com/q/3165/10691 http://www.unlimitednovelty.com/2012/03/dont-use-bcrypt.html