I am trying to compare two passwords using bcrypt. The hashed password is stored in the database as a string. When I compare the two hashed passwords (the one from the database and the one from the user), I make sure they are both encoded, but the passwords still do not match. Why do the hashed passwords not match when I store it in a database? Is it because the salt is different than when the hash password was originally generated? If so, how am I supposed to check that a password matches what is stored in a database? code: import os import bcrypt from sqlalchemy import Column, Integer, String, create_engine from sqlalchemy.orm import declarative_base, sessionmaker Base = declarative_base() os.remove("users.db") if os.path.exists("users.db") else None engine = create_engine("sqlite:///users.db") Session = sessionmaker(bind=engine) session = Session() class User(Base): __tablename__ = "users" id = Column(Integer, primary_key=True) username = Column(String(50), unique=True, nullable=False) password_hash = Column(String(100), nullable=False) Base.metadata.create_all(engine) def hash_password(password: str) -> str: hashed = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()) return hashed.decode("utf-8") def create_user(username: str, password: str) -> None: hashed_password = hash_password(password) user = User(username=username, password_hash=hashed_password) session.add(user) session.commit() print(f"User '{username}' created.") print(f'password: {password}') print(f'password_hash: {hashed_password}') print() def verify_password(username: str, password_to_check: str) -> bool: user = session.query(User).filter_by(username=username).first() if not user: print("User not found.") return False match = bcrypt.checkpw( hash_password(password_to_check).encode('utf-8'), user.password_hash.encode("utf-8") ) if match: print("Password match!") else: print("Password does not match.") print('password_to_check:', password_to_check) print('password_to_check (encode):', hash_password(password_to_check).encode('utf-8')) print('user.password_hash:', user.password_hash) print('user.password_hash (encode):', user.password_hash.encode('utf-8')) return match # Create a user create_user("alice", "my_secure_password") # Try to verify password verify_password("alice", "my_secure_password") # Should match print() verify_password("alice", "wrong_password") # Should not match print() output: User 'alice' created. password: my_secure_password password_hash: $2b$12$Q3NmS7nQ.hvg7NnUk8bONO3.tVHmB0IC758BBKXXzT2omFuBp4xd2 Password does not match. password_to_check: my_secure_password password_to_check (encode): b'$2b$12$veGsFll.mjNjK10GXYYLqe9at/9FN.2Ue12T.l9BedjbHIQmEVWDe' user.password_hash: $2b$12$Q3NmS7nQ.hvg7NnUk8bONO3.tVHmB0IC758BBKXXzT2omFuBp4xd2 user.password_hash (encode): b'$2b$12$Q3NmS7nQ.hvg7NnUk8bONO3.tVHmB0IC758BBKXXzT2omFuBp4xd2' Password does not match. password_to_check: wrong_password password_to_check (encode): b'$2b$12$x6CdcXKwfIjgwcAWiAkU8.1ukRrKUVmgmBFY5Sw438odzK6X7D4fG' user.password_hash: $2b$12$Q3NmS7nQ.hvg7NnUk8bONO3.tVHmB0IC758BBKXXzT2omFuBp4xd2 user.password_hash (encode): b'$2b$12$Q3NmS7nQ.hvg7NnUk8bONO3.tVHmB0IC758BBKXXzT2omFuBp4xd2' Even in this most basic example, they still do not match: match = bcrypt.checkpw( hash_password('my_secure_password').encode('utf-8'), hash_password('my_secure_password').encode("utf-8")) > False Continue reading...