Exercise 1: Why BCryptSHA256PasswordHasher Was Needed — Possible Solution ==================================================================== THE ACTUAL PROBLEM ------------------------------ Per this chapter, the existing live site stores its admin password as a bcrypt hash - a string starting with $2b$. Django's own default password hasher is PBKDF2, a genuinely different algorithm. Without any change, Django would have no way to correctly verify a login attempt against a hash it doesn't know how to interpret. WHY ADDING THE HASHER SOLVES IT WITHOUT A PASSWORD RESET ------------------------------ Per this chapter, Django ships BCryptSHA256PasswordHasher built in already - it simply isn't enabled in PASSWORD_HASHERS by default. Once added to that list, Django's authentication reads a stored hash's own algorithm prefix and automatically selects the matching hasher, regardless of which hasher is listed first. This means the existing bcrypt hash can be verified correctly exactly as it already is, with no need to know or reset the admin's actual password - Django simply gains the ability to recognize and check a hash format it previously couldn't. WHY PBKDF2 STAYS FIRST IN THE LIST ------------------------------ PBKDF2PasswordHasher remains first because it's still Django's own preferred hasher for any NEW password going forward - the bcrypt hasher is added specifically to handle the one existing legacy hash, not to replace Django's own default for future use. WHY THIS WORKS AS AN ANSWER ------------------------------ It correctly explains the mismatch between the existing bcrypt hash and Django's PBKDF2 default, and correctly explains that adding BCryptSHA256PasswordHasher to PASSWORD_HASHERS (rather than changing the default) is what allows Django to recognize and verify the existing hash without requiring a password reset.