在开发用户身份验证系统时,如何安全地存储和验证密码是一个关键问题。本文将深入探讨单向哈希算法(bcrypt、scrypt、Argon2)的工作原理,并讲解如何确保密码验证时使用相同的哈希算法和参数,以保证验证过程的一致性和安全性。
1. 为什么不能直接存储密码?
如果直接在数据库中存储明文密码,一旦数据库泄露,攻击者将能直接获取所有用户的密码。因此,所有安全的系统都使用哈希算法对密码进行单向加密,确保即使数据库被攻破,密码仍然难以被恢复。
但仅仅使用哈希函数(如 SHA-256
)是不够的,因为没有加盐(Salt),攻击者可以使用彩虹表破解密码。因此,我们需要使用更安全的密码哈希算法,如 bcrypt
、scrypt
或 Argon2
。
2. 安全密码存储:bcrypt、scrypt 和 Argon2
不同的密码哈希算法在安全性、计算成本和易用性上有所不同,我们分别介绍它们的原理和使用方式。
① bcrypt(最广泛使用)
✅ 特点:
- 适用于大多数 Web 应用
- 自动生成盐(Salt),并将盐嵌入哈希值中
- 工作因子(cost factor) 控制计算复杂度,增加破解难度
🔹 存储格式(包含盐和参数):
$2b$12$EIX8s2yLd7vL9hZ37UbyCeWdLzH7ZZhAo6Zh8D/Umu1txPO0y9H0y
\__/ \__/ \_________________________/ \____________________/
│ │ │ │
│ │ │ └── 计算得到的哈希值
│ │ └── 盐(Salt)
│ └── 工作因子 cost(12 表示 2^12 轮计算)
└── 哈希算法标识($2b$ 表示 bcrypt)
🔹 密码哈希(Python 实现):
import bcrypt
password = b"password123"
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt()) # 生成哈希
print(hashed_password) # 存储到数据库
🔹 密码验证(自动使用相同参数):