本文目录导读:

- 方法一:使用
bcrypt(最推荐) - 方法二:使用
werkzeug.security(Flask常用) - 方法三:使用
hashlib+secrets(手动实现,不推荐新手) - 🚨 重要安全建议
- 完整实战示例(数据库场景)
- 总结推荐
在Python中加密用户密码时,绝对不要使用简单的哈希算法(如MD5、SHA1),因为它们不够安全,推荐使用以下两种主流方法:
使用 bcrypt(最推荐)
bcrypt 内置盐值(salt),能自动抵抗彩虹表攻击,且计算速度可调。
安装
pip install bcrypt
加密与验证示例
import bcrypt
# 1. 注册时:加密密码
def hash_password(password: str) -> str:
# 自动生成盐值并哈希,返回bytes类型
hashed = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
return hashed.decode('utf-8') # 转为字符串方便存储
# 2. 登录时:验证密码
def check_password(password: str, hashed_password: str) -> bool:
return bcrypt.checkpw(
password.encode('utf-8'),
hashed_password.encode('utf-8')
)
# 使用示例
user_password = "MySecurePass123!"
stored_hash = hash_password(user_password)
print(f"存储的哈希值: {stored_hash}")
# 验证密码
is_valid = check_password("MySecurePass123!", stored_hash)
print(f"密码正确: {is_valid}") # True
is_valid_wrong = check_password("WrongPass!", stored_hash)
print(f"密码错误: {is_valid_wrong}") # False
使用 werkzeug.security(Flask常用)
如果你使用Flask框架,它内置了密码加密工具。
安装
pip install werkzeug
加密与验证示例
from werkzeug.security import generate_password_hash, check_password_hash
# 加密密码(默认使用pbkdf2:sha256算法)
hashed_password = generate_password_hash("MySecurePass123!")
print(f"哈希值: {hashed_password}")
# 验证密码
is_correct = check_password_hash(hashed_password, "MySecurePass123!")
print(f"验证结果: {is_correct}") # True
使用 hashlib + secrets(手动实现,不推荐新手)
如果你不想安装第三方库,Python内置库可以实现,但需要手动处理盐值:
import hashlib
import secrets
def hash_password(password: str) -> str:
"""生成盐值并哈希密码"""
salt = secrets.token_hex(16) # 生成16字节的随机盐值
pwd_hash = hashlib.sha256((salt + password).encode()).hexdigest()
return f"{salt}${pwd_hash}" # 存储时带上盐值
def check_password(password: str, stored: str) -> bool:
"""验证密码"""
salt, pwd_hash = stored.split('$')
return hashlib.sha256((salt + password).encode()).hexdigest() == pwd_hash
# 使用示例
stored = hash_password("MySecurePass123!")
print(f"存储值: {stored}")
# 验证
print(check_password("MySecurePass123!", stored)) # True
print(check_password("WrongPass!", stored)) # False
🚨 重要安全建议
-
绝不使用MD5/SHA1:
# ❌ 错误示例 - 绝不这样做 hashlib.md5(password.encode()).hexdigest() hashlib.sha1(password.encode()).hexdigest()
-
加盐(Salt):每个密码使用不同的随机盐值
-
使用慢哈希算法:
bcrypt、argon2、scrypt等是专门为密码设计的慢哈希算法 -
不要自己实现加密算法:使用经过安全验证的库
完整实战示例(数据库场景)
import bcrypt
import sqlite3
class UserAuth:
def __init__(self, db_path: str = "users.db"):
self.conn = sqlite3.connect(db_path)
self._create_table()
def _create_table(self):
self.conn.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE,
password_hash TEXT
)
""")
self.conn.commit()
def register(self, username: str, password: str) -> bool:
"""用户注册"""
password_hash = bcrypt.hashpw(
password.encode('utf-8'),
bcrypt.gensalt()
).decode('utf-8')
try:
self.conn.execute(
"INSERT INTO users (username, password_hash) VALUES (?, ?)",
(username, password_hash)
)
self.conn.commit()
return True
except sqlite3.IntegrityError:
return False # 用户名已存在
def login(self, username: str, password: str) -> bool:
"""用户登录验证"""
cursor = self.conn.execute(
"SELECT password_hash FROM users WHERE username = ?",
(username,)
)
result = cursor.fetchone()
if result is None:
return False
stored_hash = result[0]
return bcrypt.checkpw(
password.encode('utf-8'),
stored_hash.encode('utf-8')
)
# 使用示例
auth = UserAuth()
# 注册
if auth.register("alice", "SecurePass123!"):
print("注册成功")
else:
print("用户名已存在")
# 登录
if auth.login("alice", "SecurePass123!"):
print("登录成功")
else:
print("用户名或密码错误")
总结推荐
- 个人项目/学习:使用
bcrypt(最简单安全) - Flask项目:使用
werkzeug.security - 生产环境:推荐
argon2-cffi(目前最安全的密码哈希算法)
密码加密不是为了保护数据库被攻破时的数据,而是为了即使数据库泄露,攻击者也无法轻易还原用户原始密码。