Of course! In Python, "set password" can mean a few different things depending on the context:

- Hashing a password for storage: This is the most common and secure practice. You never store a password in plain text. Instead, you "hash" it (a one-way process that creates a unique, irreversible string).
- Prompting a user to enter a password: This is about getting input from the command line securely (without showing the characters as they type).
- Changing a password in a system: This involves a more complex workflow, like verifying the old password before setting a new one.
Let's cover each of these with clear examples.
Hashing a Password for Secure Storage (The Most Important Concept)
This is the fundamental rule of password security: NEVER store passwords in plain text. If your database is ever compromised, hashed passwords are useless to an attacker.
We use a strong, modern hashing algorithm like bcrypt. It's designed to be slow, which makes brute-force attacks much harder.
Step 1: Install the bcrypt library
It's not part of the standard library, so you need to install it first.
pip install bcrypt
Step 2: Hash the Password
Here's how to hash a password. Notice that the function also generates a "salt" for you, which adds randomness to the hash.
import bcrypt
# The password you want to hash (as bytes)
# In a real app, you'd get this from user input.
password = "my_super_secret_password_123".encode('utf-8')
# Generate a salt and hash the password
# The 'gensalt' function creates a random salt for you.
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())
print(f"Original Password: {password.decode('utf-8')}")
print(f"Hashed Password: {hashed_password.decode('utf-8')}")
# Example Output (will be different every time due to the salt):
# Original Password: my_super_secret_password_123
# Hashed Password: $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LeZeUfkZMBs9kYZP6
Key points:
- You must encode the string to bytes using
.encode('utf-8')before hashing. - The output includes the algorithm version, the cost factor (work factor), the salt, and the hash itself. This single string is everything you need to store in your database.
Verifying a Password (The Other Half of the Story)
Hashing is useless without a way to verify. When a user tries to log in, you take the password they provide, hash it using the same salt from your stored hash, and compare the results.
bcrypt makes this incredibly easy.
import bcrypt
# --- This is what you have stored in your database ---
stored_hashed_password = b'$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LeZeUfkZMBs9kYZP6'
# --- This is what the user enters on the login form ---
login_attempt_1 = "my_super_secret_password_123".encode('utf-8')
login_attempt_2 = "this_is_the_wrong_password".encode('utf-8')
# Check the first attempt
if bcrypt.checkpw(login_attempt_1, stored_hashed_password):
print("Login successful! Password matches.")
else:
print("Login failed! Password does not match.")
# Check the second attempt
if bcrypt.checkpw(login_attempt_2, stored_hashed_password):
print("Login successful! Password matches.")
else:
print("Login failed! Password does not match.")
Output:
Login successful! Password matches.
Login failed! Password does not match.
Prompting a User to Enter a Password Securely
When you ask a user for their password on the command line, you shouldn't display their characters. The getpass module is perfect for this.
import getpass
# Use getpass to prompt for a password without echoing it to the terminal
password = getpass.getpass("Enter your password: ")
print(f"You entered a password of length: {len(password)}")
# Now you can hash it for storage
import bcrypt
hashed_pw = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
print(f"Your hashed password is: {hashed_pw.decode('utf-8')}")
When you run this, it will look like this (the characters you type will not be visible):
Enter your password:
You entered a password of length: 12
Your hashed password is: $2b$12$n8f3Kz0sZ3o1kYv5J6lA5O9i8j7h6g5f4d3c2b1a0
Complete Example: A Simple Password Setter
This script combines all the concepts above. It prompts the user for a new password, hashes it, and "stores" it (in a variable for this example). Then it simulates a login.
import bcrypt
import getpass
# --- This is your "database" (just a variable in this example) ---
user_db = {
"admin": None # Initially, no password is set for the admin user
}
def set_password(username):
"""Prompts the user to set a new password for a given username."""
print(f"\n--- Setting password for {username} ---")
while True:
password = getpass.getpass("Enter new password: ")
if len(password) < 8:
print("Error: Password must be at least 8 characters long.")
continue
confirm_password = getpass.getpass("Confirm new password: ")
if password != confirm_password:
print("Error: Passwords do not match. Please try again.")
continue
# If we get here, passwords match and are long enough
# Hash the password and store it in our "database"
hashed_pw = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
user_db[username] = hashed_pw
print("Password set successfully!")
break
def login(username):
"""Simulates a login attempt for a given username."""
print(f"\n--- Attempting login for {username} ---")
if user_db.get(username) is None:
print(f"Error: User '{username}' not found or has no password set.")
return
password_attempt = getpass.getpass("Enter your password to login: ")
stored_hash = user_db[username]
if bcrypt.checkpw(password_attempt.encode('utf-8'), stored_hash):
print("Login successful! Welcome.")
else:
print("Login failed! Incorrect password.")
# --- Main Program Execution ---
if __name__ == "__main__":
# 1. Set a password for the first time
set_password("admin")
# 2. Try to log in with the correct password
login("admin")
# 3. Try to log in with the wrong password
login("admin")
# 4. Try to log in for a user that doesn't exist
login("guest")
Summary of Best Practices
- ALWAYS Hash Passwords: Never store them in plain text.
- Use a Strong Algorithm: Use
bcryptorargon2.bcryptis the most common and a great choice. - Generate a Salt for Each Password:
bcrypt.hashpw()does this for you automatically. - Use
getpassfor Input: When asking for passwords on the command line, usegetpass.getpass()to hide the input. - Verify with
bcrypt.checkpw(): This function securely compares the user's input with the stored hash. Do not try to compare them manually. - Enforce Password Policies: Check for minimum length, complexity, etc., before hashing.
