P34 用户忘记密码,系统为什么不直接提供密码,而是要修改密码
面试题:用户忘记密码,为什么系统不能把原密码直接告诉他,而只能重置?
核心答案
因为系统里根本没有存你的明文密码,无法告诉你;而且即使存了,直接告知明文密码本身就是巨大的安全风险。
1. 密码的正确存储方式:只存哈希,不存明文
text
注册时:password → 加盐哈希(如 BCrypt)→ 存储 password_hash
登录时:输入密码 → 同样加盐哈希 → 与存储值比对- 即使数据库被拖库,攻击者拿到的也是哈希值,无法直接还原明文;
- 所以"忘记密码"时系统没有明文可给,只能让你重置为新密码。
2. 为什么不能直接提供/找回明文密码
① 技术上做不到
哈希是单向函数(如 BCrypt、PBKDF2、Argon2),无法从哈希反推明文,系统自己也不知道你的密码是什么。
② 即使能做到也不该做
- 明文密码在系统里可被读取,等于给攻击者留了后门(DBA、运维、泄露都危险);
- 用户常常多平台共用同一密码,泄露一个等于一串账号沦陷;
- 合规要求(等保、GDPR 等)也禁止明文存储/传输。
3. 正确的"忘记密码"流程
text
用户申请重置 → 验证身份(邮箱/手机验证码,甚至二次验证)→
服务端生成一次性重置链接/验证码(短期有效)→ 用户设置新密码 → 完成关键点:
- 验证码/链接一次性,过期作废;
- 重置成功后所有旧会话/Token 失效(防已泄露会话继续使用);
- 重置链接不要直接带明文新密码,而是引导用户自己设置;
- 记录安全日志(IP、设备、时间),异常行为告警。
4. 加分点
- 追问"哈希是不是就安全了":还需要加盐防彩虹表、用慢哈希算法(BCrypt 自带盐和成本因子)防暴力破解;
- 追问"为什么不能用 MD5/SHA1":无盐 + 速度快,极易被彩虹表/暴力破解;
- 登录要做失败次数限制、验证码、风控,与密码存储配套。
一句话总结
系统只存密码的加盐哈希、不存明文(单向不可逆),所以忘记密码时无法告知原密码;正确做法是验证身份后让用户重置新密码,并让旧凭证失效,这既是技术约束也是安全设计。