
1) 【一句话结论】:在密码存储中,哈希函数通过添加随机盐并多次迭代计算,生成唯一且抗暴力破解的哈希值,有效抵御彩虹表攻击和哈希碰撞风险,保障用户密码安全。
2) 【原理/概念讲解】:哈希函数的核心是单向压缩(输入任意长,输出固定长),但直接存储密码哈希易被彩虹表破解(预计算所有常见密码的哈希)。加盐(随机字符串,如16字节随机数)是为了每个密码的哈希值唯一,即使密码相同,加盐后哈希不同;多次哈希(如BCrypt的1000次迭代)是为了增加计算成本,使暴力破解时间指数级增长。类比:给每个密码锁加一个独一无二的锁芯(盐),然后多次转动钥匙(迭代哈希),破解者需要尝试更多组合才能找到正确钥匙。
3) 【对比与适用场景】:
| 特性 | 普通哈希(如MD5) | 加盐+多次哈希(如BCrypt) |
|---|---|---|
| 加盐 | 否(无随机盐) | 是(存储随机盐,与密码结合) |
| 迭代次数 | 1次(单次哈希) | 多次(如1000次迭代) |
| 安全性 | 低(易被彩虹表破解,碰撞风险高) | 高(防彩虹表,抗暴力破解,碰撞概率极低) |
| 适用场景 | 非密码存储(如文件校验) | 密码存储(用户登录验证) |
| 注意点 | 不可用于密码存储(易破解) | 必须存储盐(否则无法验证) |
4) 【示例】:伪代码展示BCrypt的密码存储流程。
function storePassword(username, password):
salt = generateRandomString(16) // 16字节随机盐
hashed = bcrypt.hashpw(password + salt, bcrypt.gensalt(rounds=1000)) // 1000次迭代
store(username, salt, hashed) // 存储盐和哈希值
验证时:
function verifyPassword(username, password):
storedSalt, storedHash = retrieve(username)
if bcrypt.checkpw(password + storedSalt, storedHash):
return true
else:
return false
5) 【面试口播版答案】:(约80秒)
“面试官您好,哈希函数在密码存储中用于将用户密码转换为固定长度的哈希值,但直接存储易被彩虹表破解。首先,加盐是为了每个密码的哈希值唯一,即使密码相同,加盐后哈希不同,防止彩虹表攻击。其次,多次哈希(如BCrypt的1000次迭代)是为了增加计算成本,对抗暴力破解,因为破解者需要尝试更多组合才能找到正确哈希。哈希碰撞是指不同输入得到相同哈希,虽然概率极低,但强哈希算法(如BCrypt)通过增加迭代次数和随机盐,显著降低了碰撞风险。总结来说,加盐和多次哈希共同作用,使密码存储更安全,能有效抵御常见攻击。”
6) 【追问清单】:
7) 【常见坑/雷区】: