How to Hash a Password#
argon2-cffi comes with an high-level API and uses the officially recommended low-memory Argon2 parameters that result in a verification time of 40–50ms on recent-ish hardware.
The current memory requirement is set to rather conservative 64 MB. However, in memory constrained environments such as Docker containers that can lead to problems. One possible non-obvious symptom are apparent freezes that are caused by swapping.
Please check Choosing Parameters for more details.
Unless you have any special requirements, all you need to know is:
>>> from argon2 import PasswordHasher >>> ph = PasswordHasher() >>> hash = ph.hash("correct horse battery staple") >>> hash '$argon2id$v=19$m=65536,t=3,p=4$MIIRqgvgQbgj220jfp0MPA$YfwJSVjtjSU0zzV/P3S9nnQ/USre2wvJMjfCIjrTQbg' >>> ph.verify(hash, "correct horse battery staple") True >>> ph.check_needs_rehash(hash) False >>> ph.verify(hash, "Tr0ub4dor&3") Traceback (most recent call last): ... argon2.exceptions.VerifyMismatchError: The password does not match the supplied hash
A login function could thus look like this:
import argon2 ph = argon2.PasswordHasher() def login(db, user, password): hash = db.get_password_hash_for_user(user) # Verify password, raises exception if wrong. ph.verify(hash, password) # Now that we have the cleartext password, # check the hash's parameters and if outdated, # rehash the user's password in the database. if ph.check_needs_rehash(hash): db.set_password_hash_for_user(user, ph.hash(password))
argon2.PasswordHasher class has the aspiration to be good to use out of the box, it has all the parametrization you’ll need.