पाठ 22 / 26
Password Hashing
Never store plain passwords.
Salted, slow hashes
Django stores passwords as salted, deliberately slow hashes (PBKDF2 by default, with Argon2 and bcrypt available) and verifies them with check_password; the iteration count rises with each release to keep pace with hardware. Use the built-in auth system or make_password rather than inventing your own hashing. In FastAPI projects, use a maintained library (such as pwdlib or passlib with Argon2) for the same purpose.
Hashing and verifying a password, run
I ran this script with python manage.py shell --no-imports in the demo project (Django 6.1.1, SQLite). The default algorithm is PBKDF2-SHA256 with 1,500,000 iterations in Django 6.1 and a random salt, so hashing the same password twice gives different hashes; check_password verifies correctly.
from django.contrib.auth.hashers import check_password, make_password
h = make_password("correct horse battery staple")
algo, iterations, salt, digest = h.split("$")
print(algo, "iterations:", iterations, "| salted:", len(salt) > 0)
print("verify right:", check_password("correct horse battery staple", h))
print("verify wrong:", check_password("hunter2", h))
print("same password, different hash:", make_password("x") != make_password("x"))
Output:
pbkdf2_sha256 iterations: 1500000 | salted: True verify right: True verify wrong: False same password, different hash: True
Consider Argon2
Adding argon2-cffi and listing the Argon2 hasher first upgrades password storage; old hashes are upgraded on next login.
त्वरित जाँच: Why does the same password produce different hashes?
- Hashes include the current time only
- The hash function is broken
- The password changes
- Each hash uses a random salt
Answer
Each hash uses a random salt — Salts defeat precomputed attacks.