密码哈希与彩虹表攻击详解
字数 1558 2025-11-11 19:59:59
密码哈希与彩虹表攻击详解
一、知识点描述
密码哈希是存储用户密码的常见安全实践,核心思想是通过单向哈希函数(如MD5、SHA-256、bcrypt)将明文密码转换为固定长度的密文。即使数据库泄露,攻击者也无法直接还原密码。但单纯的哈希仍存在风险,例如彩虹表攻击通过预计算哈希值与明文的映射关系,可快速破解弱密码的哈希值。本知识点将涵盖密码哈希的基本原理、彩虹表攻击的工作流程,以及现代密码存储的防御措施(如加盐、慢哈希函数)。
二、密码哈希的基本原理
-
哈希函数的特性
- 单向性:从哈希值无法反推明文(抗第一原像性)。
- 确定性:相同输入始终产生相同输出。
- 雪崩效应:微小输入变化导致哈希值剧烈变化。
- 常见算法:MD5(已不安全)、SHA-1(弱化)、SHA-256、bcrypt、Argon2。
-
为何需要哈希存储密码?
- 防止数据库泄露后密码被直接使用(避免明文存储的致命风险)。
- 示例:用户密码
123456→ SHA-256 哈希值为8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92。
三、彩虹表攻击的原理与步骤
问题背景:单纯哈希的缺陷在于,相同密码的哈希值一致。攻击者可提前预计算常见密码的哈希值,形成“哈希表”(如 password→哈希值 的映射),通过查表快速破解。
彩虹表的优化:
-
减少存储空间:传统哈希表需存储所有明文-哈希值对,占用巨大空间。彩虹表通过哈希链压缩数据:
- 定义还原函数(R):将哈希值映射回一个明文(非真正还原,而是生成一个可能的明文,如取哈希值前6位作为伪明文)。
- 构建链:明文1 → 哈希函数(H) → 哈希值1 → 还原函数(R) → 明文2 → H → 哈希值2 → R → 明文3…
- 仅存储链的起点(明文1)和终点(明文n),中间节点全部丢弃。
-
攻击流程:
- 预计算阶段:生成多条哈希链,存储起点和终点。
- 破解阶段:
a. 获取目标哈希值H_target。
b. 对H_target交替应用 R 和 H,生成一条新链,每步的终点与预计算表的终点对比。
c. 若匹配到某条链的终点,从该链起点重新计算整条链,找到与H_target对应的明文。
示例简化:
假设还原函数 R 为取哈希值首字符(实际更复杂),链长为3:
- 链1:
abc→ H → 哈希1 → R →x→ H → 哈希2 → R →def(存储起点abc和终点def)。 - 破解哈希2时:哈希2 → R →
def(匹配终点)→ 从起点abc重算链找到哈希2对应明文x。
四、防御彩虹表攻击的关键技术
-
加盐(Salting)
- 为每个密码生成随机盐值(如12字节),与密码拼接后哈希:
哈希(盐 + 密码)。 - 作用:相同密码因盐值不同产生不同哈希值,使预计算的彩虹表失效。
- 存储:将盐值与哈希值共同存入数据库(例:
盐值:哈希值)。
- 为每个密码生成随机盐值(如12字节),与密码拼接后哈希:
-
慢哈希函数(Key Stretching)
- 使用多次迭代的哈希算法(如bcrypt、PBKDF2),增加计算成本,降低暴力破解速度。
- 例:bcrypt 的工作因子(cost factor)可调整迭代次数,使单个哈希计算耗时约0.1秒。
-
现代密码存储方案
- 推荐组合:
随机盐 + 慢哈希函数(如bcrypt/Argon2)。 - 代码示例(Python bcrypt):
import bcrypt password = "user123".encode('utf-8') salt = bcrypt.gensalt(rounds=12) # 工作因子=12 hashed = bcrypt.hashpw(password, salt) # 存储 hashed(已包含盐值)
- 推荐组合:
五、总结
- 单纯哈希易受彩虹表攻击,因相同密码哈希值一致。
- 彩虹表通过哈希链平衡存储与计算效率,但加盐可彻底破解其有效性。
- 现代系统必须使用随机盐+慢哈希,并选择bcrypt、Argon2等抗ASIC/GPU的算法。