Solution to Challenge #3
The code for this can be found in this repo: https://github.com/The-Polymath-dev/3-basic-auth.
It is a containerized setup for MySQL and the Python script which does login and register.
Let’s skip to the main part, the password hashing and checking.
Password hashing
# Hash password
password_hash = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())password.encode('utf-8'): Converts the password string to bytes (bcrypt requires bytes input)bcrypt.gensalt(): Generates a random salt (adds randomness to prevent rainbow table attacks)
bcrypt.hashpw(): Combines the password and salt to create a secure hash
Password verification
if bcrypt.checkpw(password.encode('utf-8'), stored_hash.encode('utf-8')):
return "Login successful!"Takes the input password and the stored hash and uses the same hashing process to verify if they match.
Why Bcrypt?
Built-in Salt: Automatically generates and stores a unique salt with each hash
Adaptive Cost: Can be adjusted to remain secure as computers get faster
Slow by Design: Makes brute-force attacks computationally expensive
Security Features:
One-way function: You can't reverse the hash to get the original password
Same password hashes differently each time due to different salts
Resistant to rainbow table attacks due to salting
Computationally intensive, making bulk cracking attempts difficult
Example of how the same password produces different hashes:
password = "password123"
hash1 = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
hash2 = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
print(hash1) # Different from hash2
print(hash2) # Different from hash1
# But bcrypt.checkpw() will verify both as correct!This is why we can safely store the hash in the database without ever storing the actual password.
Some security breaches in the past due to poor handling of passwords.

