3-1 密码安全及相关知识(什么是彩虹表攻击)
本节系统讲解密码安全的核心原理,包括用户注册流程的安全设计、哈希加密机制、彩虹表攻击原理与防范策略,以及常见加密库的选型对比。
用户注册安全流程
一个安全的用户注册流程应包含以下步骤:
前端提交数据
→ 后端接收数据
→ Pipe 校验(密码长度、复杂度)
→ Service 层查询用户是否已存在(读操作,非写操作)
→ 密码哈希加密
→ 写入数据库
→ 脱敏处理后返回响应(含 Token)
text
关键设计原则:先读后写。数据库读操作性能远优于写操作,先查询用户名是否已存在可以避免恶意注册对数据库造成写入压力。
防恶意注册的策略
| 策略 | 说明 |
|---|---|
| 用户名预查 | 注册前先查询用户名是否已存在 |
| 图片验证码 | 图形、滑块、点选等验证方式 |
| 注册频率限制 | 单 IP 每日注册次数上限 |
| 接口限流 | 单 IP 每秒/每分钟请求次数限制 |
| 封禁策略 | 异常 IP 自动封禁 |
密码哈希化
明文存储密码极其危险。哈希(Hash)是通过加密算法将原始密码转换为不可逆的固定长度字符串:
原始密码: "123456"
↓ 哈希算法
哈希结果: "$argon2id$v=19$m=65536,t=3,p=4$c2FsdA$hash..."
text
常见哈希算法与库:
| 库/算法 | 特点 |
|---|---|
crypto(Node.js 内置) | 需手动拼接盐值,使用繁琐 |
bcrypt | 经典方案,对 Node 版本要求高,加密性能较低 |
argon2 | 推荐,自动处理盐值,性能优秀,安全性高 |
| MD5 / SHA | 已不推荐用于密码存储,易被破解 |
彩虹表攻击
攻击原理:
彩虹表是一个预计算的海量数据库,存储了常见密码与对应哈希值的映射关系。攻击者通过比对目标系统数据库中的哈希值与彩虹表中的记录,反推原始密码。
攻击者的彩虹表数据库:
┌──────────────┬─────────────────────────────┐
│ 原始密码 │ MD5 哈希值 │
├──────────────┼─────────────────────────────┤
│ 123456 │ e10adc3949ba59abbe56e057f20 │
│ password │ 5f4dcc3b5aa765d61d8327deb8 │
│ qwerty │ d8578edf8458ce06fbc5bb76 │
│ ... │ ... │
└──────────────┴─────────────────────────────┘
攻击流程:
1. 攻击者获取目标数据库中的哈希值
2. 逐条在彩虹表中查找匹配
3. 找到匹配 → 获得原始密码 → 攻击成功
text
为何哈希仍不安全:常见哈希算法(MD5、SHA 等)是公开的,攻击者只需维护足够大的彩虹表即可覆盖大量常用密码。
盐值(Salt)防范彩虹表攻击
盐值是一串随机字符串,在哈希运算前与密码拼接,使相同的密码产生不同的哈希结果:
无盐值:
"123456" → hash("123456") → "e10adc3949ba59abbe..."
有盐值:
"123456" + "a7x9$k2m" → hash("123456a7x9$k2m") → "f3b2c8d1e4..."
"123456" + "p4q8!w3n" → hash("123456p4q8!w3n") → "7d9a1e5c3b..."
text
盐值的特性:
- 长度通常为 16-64 位随机字符串
- 每个用户使用不同的盐值
- 盐值与哈希结果一同存储(无需保密,只需唯一)
- 攻击者无法预计算包含所有可能盐值的彩虹表
加密库选型对比
| 特性 | argon2 | bcrypt | crypto(Node 内置) |
|---|---|---|---|
| 自动盐值管理 | 内置自动处理 | 内置自动处理 | 需手动生成和拼接 |
| API 简洁度 | hash() + verify() | hash() + compare() | 需多步操作 |
| 性能 | 高(Rust 实现) | 较低(CPU 密集) | 中等 |
| 安全性 | 2015 年密码哈希竞赛冠军 | 成熟可靠 | 取决于算法选择 |
| Node 兼容性 | 无特殊要求 | 对 Node 版本要求高 | 内置,无依赖 |
推荐:argon2 是目前密码哈希的首选方案,兼具安全性、性能和易用性。
安全建议
- 不同网站使用不同密码,推荐使用密码管理器(1Password、Bitwarden 等)
- 服务端绝不存储明文密码
- 使用带盐值的哈希算法(argon2 自动处理)
- 对注册/登录接口实施频率限制
- 定期检查并清理数据库中的脏数据
↑