99password 技术说明
一个主密码,保护所有账号 · 不存储 · 不联网 · 不泄露
一、工作原理
99password 帮你解决一个现实问题:记住一个主密码,就能为每个网站生成不同的强密码。不需要密码管理器,不需要云端同步,不需要记住任何东西。
记住一个主密码,配合不同的站点标识,为每个网站生成唯一的强密码。
无需数据库,无需云端同步——同样的输入永远产出同样的输出。
无需数据库,无需云端同步——同样的输入永远产出同样的输出。
1.1 计算流程
主密码 (Master Password)
+
站点标识 (如 taobao)
↓ Argon2id 派生
32 字节哈希值
↓ 拒绝采样映射
20 位强密码
1.2 具体步骤
- 构造 Salt:
salt = "flowerpassword-v2:" + 站点标识 - Argon2id 派生:以主密码为输入、上述 Salt 为盐,执行 Argon2id 运算,输出 32 字节
- 字符映射:将 32 字节通过拒绝采样映射到 70 字符的字符集,取前 20 位作为最终密码
// 伪代码
salt = "flowerpassword-v2:" + siteKey
hash = Argon2id(password=masterPwd, salt=salt, mem=64MB, iter=3)
password = bytesToChars(hash, length=20)
二、为什么是 Argon2id
Argon2 是 2015 年密码哈希竞赛(PHC)的冠军算法,被 IETF 标准化为 RFC 9106。Argon2id 是其推荐的混合变体。
2.1 三个变体
| 变体 | 抗 GPU | 抗侧信道 | 推荐场景 |
|---|---|---|---|
| Argon2d | 强 | 弱 | 纯服务端、无侧信道风险 |
| Argon2i | 弱 | 强 | 有侧信道风险的环境 |
| Argon2id | 强 | 强 | 通用首选 |
2.2 核心安全特性
内存硬函数(Memory-Hard Function)
Argon2id 要求 64 MB 内存才能完成一次计算。这意味着:
- GPU 攻击成本极高:显卡显存有限,无法大规模并行
- ASIC 攻击不划算:定制芯片需要大量片上存储器,成本飙升
- 暴力破解不现实:每次尝试都需要 64MB 内存 + 3 轮迭代
数据独立寻址(Data-Independent Addressing)
Argon2id 的前半程使用 Argon2i 模式(访问模式不依赖数据),后半程使用 Argon2d 模式(依赖数据)。混合设计同时抵抗 GPU 和侧信道攻击。
三、参数选择
| 参数 | 值 | 说明 |
|---|---|---|
| memorySize | 65536 KB (64 MB) | 每次计算占用的内存,越大越抗 GPU |
| iterations | 3 | 迭代轮数,增加计算时间 |
| parallelism | 1 | 并行度,浏览器单线程用 1 即可 |
| hashLength | 32 字节 | 原始哈希输出长度 |
| outputLength | 20 字符 | 最终密码长度 |
| charset | 70 字符 | 大小写 + 数字 + 8 个符号,去掉易混淆 0O1lI |
熵估算:20 位 × log₂(70) ≈ 123 bit
作为对比,AES-128 的密钥空间是 128 bit。123 bit 的密码强度已接近 AES-128,暴力破解需要 2¹²³ 次尝试。
作为对比,AES-128 的密钥空间是 128 bit。123 bit 的密码强度已接近 AES-128,暴力破解需要 2¹²³ 次尝试。
3.1 性能参考
| 设备 | 耗时 |
|---|---|
| MacBook M1 | ~120 ms |
| iPhone 13 | ~200 ms |
| 中端安卓 | ~350 ms |
| 普通笔记本 | ~500 ms |
四、为什么选 99password
4.1 与密码管理器对比
| 99password | 1Password / Bitwarden | |
|---|---|---|
| 存储方式 | 无存储,算法派生 | 加密数据库 |
| 云端同步 | 不需要 | 依赖云服务 |
| 单点故障 | 主密码泄露 → 全部泄露 | 主密码泄露 → 全部泄露 |
| 数据丢失风险 | 无(无需备份) | 有(数据库损坏/丢失) |
| 跨设备 | 任意设备,无需安装 | 需要客户端/浏览器插件 |
| 离线使用 | 完全离线 | 首次需联网同步 |
| 信任依赖 | 信任算法(公开标准) | 信任软件厂商 |
| 密码强度 | ~123 bit | 用户自定义或随机生成 |
4.2 与同类确定性密码工具对比
| 99password | 花密 (原版) | LessPass | |
|---|---|---|---|
| 哈希算法 | Argon2id (RFC 9106) | HMAC-MD5 | PBKDF2 |
| 内存硬 | 64 MB | 无 | 无 |
| 抗 GPU | 强 | 弱 | 弱 |
| 输出熵 | ~123 bit | ~80 bit | 可配置 |
| 算法标准化 | RFC 9106 | 自定义 | NIST 推荐 |
| 离线可用 | 单文件 | 单文件 | 需服务器或插件 |
4.3 核心优势总结
- 零依赖:一个 HTML 文件,双击即用,不需要服务器、数据库、浏览器插件
- 算法前沿:Argon2id 是当前最强的密码哈希算法,内存硬设计让 GPU/ASIC 攻击成本极高
- 确定性:同样输入 → 同样输出,无需备份、同步、恢复
- 完全离线:WASM 内联在 HTML 中,不联网也能用
- 透明可审计:所有代码都在一个 HTML 文件里,任何人都能审查
五、局限与注意事项
- 主密码是唯一命门:主密码泄露 = 所有站点密码泄露,务必使用高强度主密码
- 站点标识不可变:一旦注册时用
taobao作为标识,以后也必须用taobao,改了就变密码 - 无法应对站点密码策略变更:如果某网站要求特殊字符而生成的密码不含,需要单独处理
- 没有双因素认证:单因素(主密码)保护,建议主密码足够复杂
六、致敬与许可
本项目受 花密 FlowerPassword 启发。花密是国内最早的确定性密码生成工具之一,由原作者于 2011 年创建,其"可记忆、无储存"的理念影响了众多后续项目。
99password 在花密的理念基础上,将哈希算法从 HMAC-MD5 升级为 Argon2id,大幅提升了抗暴力破解能力。感谢原作者的开创性工作。
核心库:hash-wasm (MIT License)