第1章 密码迁移概述:为什么需要密码迁移?常见场景
1.1 为什么要做密码迁移?
说白了,密码迁移就是给用户的密码“搬家”——从旧存储格式搬到新存储格式。你可能会问:好端端的搬什么家?我经历过的几个项目让我特别清楚这里面的痛。
我记得有一次负责一个金融系统的安全审计,发现用户密码还在用 MD5 哈希。那真是个定时炸弹。当时数据库已经被拖了一次,好在密码是加盐的,没出大事。但从那以后,团队决定全面迁移到 bcrypt。这就是典型的密码迁移驱动场景——安全漏洞逼迫你升级。
再比如公司合并,两套用户系统要整合。 A 公司用 SHA-256 ,B 公司用 PBKDF2 。用户不能重复注册吧?那就得在后台把两边的密码存储方式统一起来。我习惯把这个过程叫“密码融冰”——慢慢化掉旧哈希,露出来新算法。
归纳起来,密码迁移的驱动力主要来自:
- 安全威胁演变:旧的哈希算法不再抗 GPU 或 ASIC 攻击。
- 合规要求:如等保 2.0、PCI-DSS 强制使用强密钥派生函数。
- 系统升级:框架升级导致密码组件不再兼容。
- 用户体验改进:支持无密码登录、多因子认证时的密码格式统一。
- 成本优化:减少维护多套密码验证逻辑的支出。
1.2 系统升级场景
系统升级是最常见的迁移场景之一。应用版本从 Spring 4 跳到 Spring Boot 3,或者从 CentOS 迁移到 Alpine 容器——底层加密库都可能变了。
我以前遇到过一个坑:旧系统用的是自定义的“base64+salt+ SHA1 ”拼接,新系统要用标准 bcrypt 。直接复制旧哈希肯定不行。我当时的解决方式是设计一个“过渡区”——在用户表加一列 hash_version ,登录时先按旧算法验证,验证通过后立刻用新算法重新哈希并更新数据库。这叫懒迁移(lazy migration)。
升级前后对比:
| 特性 | 旧系统 | 新系统 |
|---|---|---|
| 哈希算法 | MD5 + 固定盐 | bcrypt (cost=10) |
| 盐管理 | 硬编码 | 自动生成并存储 |
| 哈希长度 | 32 字节十六进制 | 60 字节 |
| 验证性能 | 微秒级 | 毫秒级(可控) |
| 抗暴力破解 | 弱 | 强(GPU 效率低) |
1.3 系统合并场景
合并是一团乱麻。我在一个收购项目中见过最典型的例子:主系统用了 Argon2id ,子公司系统还在用明文存储(别笑,真事)。
合并第一个原则:绝不能在合并过程中要求用户改密码。策略是引入一个“认证路由器”:
- 读取用户记录里的
password_hash和hash_type字段。 - 根据类型选择对应算法验证。
- 若验证通过,且哈希类型不是目标算法,就立刻迁移到目标算法并更新记录。
- 未来每次登录都会触发一次迁移机会,直到全部用户完成。
这套方案我至今在用,核心是保持向后兼容。你想想看,如果合并后 10 万用户都要重置密码,客服团队会被骂死的。
hash_type 动态创建对应的验证器。1.4 密码策略变更场景
策略变更有时候是“被迫”的——比如等保要求密码长度至少 8 位,而老用户很多是 6 位。这时候强制重置会造成极大体验伤害。
我建议的策略是分三步走:
- 阶段一(缓冲期):登录时检查密码长度,如果 < 8 位,弹提示“建议更新”,但不阻拦。
- 阶段二(渐进强制):30 天后,低于 8 位的用户在登录后强制跳转到改密页面。
- 阶段三(静默迁移):改为新密码时,自然使用新算法存储。旧算法哈希只保留用于验证旧密码,改密后立刻删除。
另外,如果策略变更涉及算法升级(比如加 salt 或换算法),懒迁移同样适用。不过要特别小心那些长期不登录的“僵尸账户”——它们可能在迁移窗口内一直没触发,最后需要批量处理。
我曾经踩过这个坑:一批休眠账户迁移遗漏,半年后用户回来登录,旧哈希已经不再支持,导致认证失败。从那以后,我总会对超过 90 天未登录的账户做一次离线批处理迁移,并发送通知。
1.5 密码迁移核心流程
三种场景看似不同,但落到底层流程是一致的。我用一张图帮你把脉络理清:
这张图揭示了密码迁移的底层逻辑:无论哪种场景,最终都要落到具体的实施动作(算法升级、用户合并、强度提升等)。后面的章节我们会逐一深入这些动作的实现细节。
1.6 避坑指南
作为过来人,我总结三个容易翻车的地方:
- 直接复制旧哈希:哈希算法不同,复制过去验证必失败。必须设计兼容验证逻辑。
- 遗漏账户锁定状态:迁移时如果误将锁定账户的密码重置,等于帮用户解锁。我曾在生产环境因为这个被运维骂惨了——记得迁移前检查
account_locked或disabled字段。 - 忘记监控迁移进度:没有 metrics 你就不知道迁移是卡住了还是完成了。我习惯在应用加一个
password_migration_pending的 Prometheus 指标,实时看剩余待迁移用户数。
1.7 本章要点
密码迁移不是一个“if-else”能解决的问题。它涉及安全、用户体验、系统兼容性三个维度。三种典型场景——系统升级、系统合并、策略变更——背后的核心手段都是懒迁移(Lazy Migration)和过渡验证。
记住:不要批量改密码,不要直接复制哈希,不要忽略休眠账户。把这些原则刻在脑子里,后面的实战内容你就能稳稳接住了。