单文件、纯 JS、零依赖、零外部请求的确定性密码管理器。双击 index.html 即可使用,也可直接部署到任意静态托管(如 GitHub Pages)。
- 实时派生,密码不落盘:站点密码由「主密码 + 站点 + 计数器」现场计算,本地只存命名空间与站点条目,不存任何密码
- 多命名空间:多主密码场景(个人 / 工作…),每个空间独立的主密码与站点列表
- 快速计算:不依赖命名空间,输入主密码/站点/计数器/模板即时派生(自动重算),可一键存为条目
- 主密码不存储、不校验:主密码仅保存在内存,锁屏即清空;设备被拿时无验证目标,无法离线爆破;但主密码本身仍应 ≥12 位(网站拖库后,弱主密码可被离线爆破)
- 纯 JS 密码学:PBKDF2-HMAC-SHA256 自实现(不依赖 WebCrypto),
file://与网页环境行为完全一致 - 8 套密码模板:字符集与模板参考官方 Master Password 算法,可复现、跨设备一致
- 危险操作二次确认:删除空间/站点必须输入
yes才执行,不可撤销 - 站点搜索、按站点名排序、深浅色跟随系统、1 分钟无操作自动锁定、JSON 导出/导入备份
- 复制自动降级:
navigator.clipboard不可用时回退execCommand("copy"),仍失败则提示长按密码文本手动复制 - 跨标签页冲突检测:数据被其他标签页修改时询问「覆盖/放弃」;存储失败(隐私模式/配额)明确告警并回滚,绝不静默丢失修改
- 双击打开
index.html - 「新建命名空间」→ 输入名称(主密码在打开空间时输入)
- 点命名空间 → 输入主密码 → 进入
- 「添加站点」→ 填写站点名 / 用户名(可选)/ 模板 / 计数器
- 点站点条目 → 密码实时生成(默认打码)→ 显示 / 复制
bytes = PBKDF2-HMAC-SHA256(主密码, "tokenpass|" + site + "|" + counter, 200000 迭代, 64 字节)
密码 = 模板映射(bytes)
- 模板映射:
bytes[0]取模选择模板变体,bytes[1+i]取模映射第 i 个字符(与官方 Master Password 的siteKey[0]/siteKey[c+1]语义一致) - 同一主密码 + 站点 + 计数器在任意设备上生成完全相同的密码
- 用户名不参与派生;站点名、主密码、计数器任一改变都会生成不同的密码
| 模板 | 长度 | 组成 | 变体数 |
|---|---|---|---|
| Maximum | 20 位 | 字母数字符号 | 2 |
| Long | 14 位 | 发音型字母数字符号 | 21 |
| Medium | 8 位 | 发音型字母数字符号 | 2 |
| Basic | 8 位 | 字母数字(无符号) | 3 |
| Short | 4 位 | 字母数字(无符号) | 1 |
| PIN | 4 位 | 纯数字 | 1 |
| Num6 | 6 位 | 纯数字 | 1 |
| Alnum12 | 12 位 | 字母数字(无符号) | 2 |
- 主密码永不落盘、永不导出、永不参与网络:只存在于内存,锁定即清空
- 主密码不校验:任意非空密码可进入空间,输错会静默生成错误密码(可通过"登不进网站"察觉)。这是有意设计——任何本地校验哈希都可被离线爆破
- 命名空间与站点条目以明文存于
localStorage(键tokenpass.namespaces.v2):防止的是"别人打开页面看到你的站点列表",而非防本地攻击者 - 换设备:导出 JSON(含全部命名空间与条目)→ 新设备导入;同名空间自动合并去重
- 主密码丢失 = 该空间所有密码永久丢失,无找回机制
- 单文件架构:HTML / CSS / 内联 JS,算法为纯函数区块(可被独立测试脚本提取对拍)
- 验证方式:
- 算法对拍:纯 JS PBKDF2 与 node
crypto.pbkdf2Sync逐字节比对(SHA-256 / PBKDF2 / 8 模板派生全覆盖) - 浏览器 E2E:Playwright 在
file://下全流程验证(解锁 → 增删改 → 派生/复制及降级 → 导出导入 → 搜索排序 → 主题 → 自动锁定)
- 算法对拍:纯 JS PBKDF2 与 node
- 性能:单次派生(200k 迭代 × 2 块)桌面浏览器约 0.5s;迭代次数是派生算法的一部分,固定
200000不可调整(调整会使所有已生成密码失效)
需要 Node.js(≥18):
node test.mjs
test.mjs 验证内容:
- 固定测试向量:6 组(含中文站点名、最大长度+特殊字符站点名),期望密码写死,页面实现与
node:crypto独立实现必须同时命中——任何改动不得改变 200000 迭代下的派生结果 - 派生对拍:多组输入 × 8 模板,纯 JS PBKDF2 与
crypto.pbkdf2Sync逐字节比对 - 模板约束:8 套模板的长度与字符集与官方 Master Password 定义逐项一致,派生结果只含允许字符
Arlon
GPL-3.0(算法部分参考 Lyndir/MasterPassword 的公开模板定义)