一文详解 Python 密码哈希库 Passlib
在用户认证系统中,密码存储是最容易被忽视但最关键的环节。很多开发者仍然习惯直接用 hashlib
做 SHA256/MD5 哈希,这在今天已经远远不够安全。
本文将系统讲解 Python 的密码哈希库 —— Passlib,包括它的安装、核心用法、常见算法(Argon2、bcrypt、PBKDF2)、进阶配置(CryptContext)、密码迁移策略(rehash-on-login),以及在 Flask / FastAPI / Django 中的集成案例,最后给出安全最佳实践。
关键词
- Python
- Passlib
- 密码哈希
- Argon2
- bcrypt
- PBKDF2
- Flask / FastAPI / Django
目录
- 为什么不用直接
hashlib
? - 安装与可选依赖
- 快速上手:CryptContext
- 常用算法示例(Argon2 / bcrypt / PBKDF2)
- CryptContext 配置与参数
- 密码迁移(rehash-on-login)
- 框架集成示例(Flask / FastAPI / Django)
- 最佳实践与安全建议
- 总结
1. 为什么不用直接 hashlib
?
hashlib
提供了 SHA256、MD5 等通用哈希算法,但它们用于密码存储存在严重缺陷:
- 速度太快,易被 GPU/ASIC 暴力破解;
- 没有内置盐(salt),容易遭受彩虹表攻击;
- 缺少迭代/成本参数,无法灵活升级安全性。
Passlib 封装了专门的密码哈希算法(如 Argon2、bcrypt、PBKDF2),并提供 自动管理策略、迁移机制,可以显著降低出错风险。
2. 安装与可选依赖
基本安装:
pip install passlib
推荐安装常见算法支持:
pip install "passlib[argon2]" # 安装 argon2 支持
pip install "passlib[bcrypt]" # 安装 bcrypt 支持
3. 快速上手:CryptContext(核心概念)
CryptContext
是 Passlib 的灵魂:
- 负责统一管理多种哈希算法;
- 识别数据库中现有哈希的算法;
- 验证密码并在需要时触发升级。
示例:
from passlib.context import CryptContextpwd_ctx = CryptContext(schemes=["pbkdf2_sha256"], deprecated="auto")hashed = pwd_ctx.hash("my-secret-password")
print(hashed)assert pwd_ctx.verify("my-secret-password", hashed)
4. 常用算法示例
Argon2(推荐)
from passlib.hash import argon2h = argon2.hash("secret")
print(argon2.verify("secret", h)) # True
或者在 CryptContext
中配置:
pwd_ctx = CryptContext(schemes=["argon2", "pbkdf2_sha256"],default="argon2",deprecated="auto"
)
bcrypt
from passlib.hash import bcrypth = bcrypt.hash("secret")
print(bcrypt.verify("secret", h)) # True
PBKDF2
from passlib.hash import pbkdf2_sha256h = pbkdf2_sha256.hash("secret")
print(pbkdf2_sha256.verify("secret", h)) # True
5. CryptContext 配置与参数
支持为不同算法单独指定参数:
pwd_ctx = CryptContext(schemes=["argon2", "bcrypt", "pbkdf2_sha256"],default="argon2",deprecated=["pbkdf2_sha256"],pbkdf2_sha256__default_rounds=260000,bcrypt__rounds=12,argon2__memory_cost=102400,argon2__time_cost=3,
)
6. 密码迁移(rehash-on-login)
核心思想:用户登录时,如果旧哈希过时,就用新算法重新哈希并保存。
hash = get_hash_from_db(user)ok, new_hash = pwd_ctx.verify_and_update(password, hash)
if not ok:raise Exception("密码错误")if new_hash:save_hash_to_db(user, new_hash) # 升级哈希
7. 框架集成示例
Flask / FastAPI
from passlib.context import CryptContextpwd_ctx = CryptContext(schemes=["argon2", "bcrypt"], default="argon2", deprecated="auto")def hash_password(password: str) -> str:return pwd_ctx.hash(password)def verify_password(password: str, hashed: str) -> bool:return pwd_ctx.verify(password, hashed)
Django
在用户首次登录时,用 pwd_ctx.verify()
验证,成功后调用 user.set_password()
将其迁移到 Django 的默认存储格式。
8. 最佳实践与安全建议
✅ 使用 Argon2 作为首选(需要安装 argon2-cffi
)。
✅ 定期提升成本参数(如 Argon2 的 time_cost
、memory_cost
)。
✅ 使用 verify_and_update()
渐进迁移,不要一次性强制用户改密码。
✅ 始终使用库提供的 hash()
与 verify()
,不要手写盐或字符串比较。
✅ 把哈希策略放在配置文件/环境变量,便于运维随时调整。
9. 总结
Passlib
是 Python 里 最完整的密码哈希库;- 通过
CryptContext
可以轻松管理多种算法、实现密码迁移; - 推荐用 Argon2(次选 bcrypt),并结合
verify_and_update()
实现无感升级。