zhmm 开源:一款基于国密算法的本地优先密码管理器
🔐 zhmm 开源:一款基于国密算法的本地优先密码管理器
Argon2id + SM4-CBC + HMAC-SM3,PyQt6 桌面 + CLI 双形态,单文件
.zmb密库,开箱即用。
🎯 缘起:为什么还需要另一个密码管理器?
市面上的密码管理器并不少:1Password、Bitwarden、KeePass……但它们要么依赖云同步,要么使用国际通用算法(AES、SHA 系列),要么在中文用户体验上差强人意。
zhmm(账号密码管理器)的出发点很简单:
- 国密合规 — 基于 SM3/SM4 国密算法,适合有国密需求的政企和个人场景
- 本地优先,绝不联网 — 无需注册账号、无需云服务,一个
.zmb文件就是全部 - 开箱即用的中文体验 — 内置 ~400 条中文站点离线词典,自动识别网站并建议标签
- GUI + CLI 双形态 — 普通用户用图形界面,开发者和极客用命令行
🔒 加密架构:国密 + Memory-Hard KDF 的硬核组合
zhmm 的加密堆栈非同一般,它不是简单地把 AES 换成 SM4 就完事,而是在每一个环节都做了慎重的设计选择。
算法栈一览
| 环节 | 算法 | 详情 |
|---|---|---|
| 密钥派生 (KDF) | Argon2id | m=64 MiB, t=3, p=1,16 字节随机盐,输出 32 字节密钥 |
| 数据加密 | SM4-CBC | 16 字节随机 IV,PKCS7 填充 |
| 完整性校验 | HMAC-SM3 | 覆盖文件头 + 密文,32 字节认证标签 |
设计上的巧思
1. 账号名也参与 KDF
大多数密码管理器只用主密码派生密钥。zhmm 的 KDF 输入是 account.utf8 + 0x00 + password.utf8。这意味着:
- 即使用户选了「123456」这样的弱密码,攻击者不知道账号名也无法破解
- 不同账号 + 相同密码 → 完全不同的密钥 → 等效于应用层常量盐
- 账号名不写入文件,解密时必须重新提供
2. Argon2id 作为 KDF
从 v0.3.0 开始,zhmm 从 PBKDF2-HMAC-SHA256 升级到了 Argon2id(2015 年 Password Hashing Competition 冠军算法)。它的 memory-hard 特性让 GPU/ASIC 并行破解的成本呈数量级上升。
默认 m=64 MiB 的参数比 OWASP 2024 建议的 m=19 MiB 基线还保守 3 倍多,单次派生约 100-500ms,体感良好。
3. 自描述的文件格式
.zmb 文件头部内嵌 Argon2 参数和随机盐/IV,这意味着未来硬件升级调高默认强度后,老文件仍能用自己存储的参数正确解密——无需每次升级都做数据迁移。
1 | magic(4B="ZHMM") | ver(1B=5) | m_cost(4B) | t_cost(4B) | p_cost(4B) |
4. 密钥分离原则
Argon2id 输出的 32 字节密钥被一分为二:前 16 字节作为 SM4 加密密钥,后 16 字节作为 HMAC-SM3 认证密钥。加密和认证使用不同的子密钥,符合密码学最佳实践。
🖥️ 功能全景
📦 单文件密库(.zmb)
整个密码库就是一个文件。备份 = 复制文件,迁移 = 复制文件。没有什么「导出数据库 → 上传云盘 → 在新机器导入」的繁琐流程。
🔐 TOTP 双因素认证
内置 RFC 6238 标准的 TOTP 实现,支持 SHA1/256/512 三种哈希算法,还额外支持 SM3-TOTP 国密扩展。
- 支持
otpauth://URI 一键解析 - 表格每一秒刷新动态码,点击即复制,10 秒后自动清空剪贴板
- TOTP Secret 仅随
.zmb加密存储,Excel 导出时刻意剥离,防止明文泄露
🏷️ 多标签 + 侧边栏 AND 筛选
每个条目可贴 0~16 个标签,左侧标签侧边栏支持多选 AND 语义筛选——选中「工作」和「重要」,只显示同时包含这两个标签的条目。
🌐 离线网址自动打标签
这是我觉得最贴心的功能之一。随包发行了一个包含约 400 条中文常用站点的离线词典,当你输入 URL 后,系统会自动识别网站并建议标签:
mail.qq.com→ 识别为「邮箱」github.com→ 识别为「代码托管」bankofchina.com→ 识别为「银行」
匹配优先级:host 精确匹配 → registrable domain 精确 → 后缀规则(.gov.cn/.edu.cn)→ 关键字规则(bank/pay/mail)。
纯离线、不联网、零网络请求——与本地优先的承诺一致。
🕘 密码历史 + 一键回滚
每个条目自动保留最近 5 次旧密码。右键「查看历史密码…」可以明文查看、复制、或一键回滚。
回滚操作采用「交换 + 压栈」语义:旧密码恢复为当前密码,当前密码压入历史栈。连续回滚两次就能回到原始状态,保留了完整的审计轨迹。
🔑 主密码原地更换
无需导出/重导入,在设置页一键完成。内部流程:自动备份 → 用旧密码解密 → 用新密码重新加密 → fsync + os.replace 原子替换。
🛡️ 防截屏(macOS/Windows)
窗口默认从系统截图/录屏中排除:
- macOS:
NSWindowSharingNone - Windows 10 2004+:
WDA_EXCLUDE_FROM_CAPTURE
可以在设置中关闭。无法防御摄像头翻拍、采集卡、虚拟机抓屏等物理层攻击——这些不在威胁模型内。
⏱️ 自动锁定 + 剪贴板自动清除
窗口失活达到设定时间后自动回到登录页,释放内存中的明文条目。复制密码或 TOTP 动态码后 10 秒自动清空剪贴板,防止忘记清理导致泄露。
🏗️ 技术架构
1 | zhmm/ |
核心依赖栈:
| 领域 | 选型 | 理由 |
|---|---|---|
| GUI 框架 | PyQt6 | 成熟稳定,跨平台一致性好 |
| 国密算法 | gmssl | SM3/SM4 的纯 Python 实现 |
| 配置加密 | cryptography (Fernet) | 业界标准,用于加密本地配置 |
| 密钥派生 | argon2-cffi | C 实现的 Argon2,速度快 |
| Excel 处理 | openpyxl | 纯 Python,无系统依赖 |
| CI 质量门禁 | ruff + mypy + pytest | 严格的代码质量和类型检查 |
💻 CLI 模式:面向开发者的另一面
除了漂亮的 GUI,zhmm 还提供了完整的 CLI,方便脚本化操作:
1 | # 搜索密码 |
🧪 质量保障
作为一个处理密码数据的工具,质量不能靠「感觉」。zhmm 的 CI 流水线设置了严格的门禁:
- ruff lint — 代码风格一致
- mypy –strict — 核心模块强制类型检查
- pytest — 146+ 个测试用例,包含 RFC 6238 全部 18 个官方测试向量
- pre-commit hooks — 提交前自动检查
只有三项全部通过,PR 才能合并。
❓ 常见问题
Q:和 Bitwarden/KeePass 比有什么优势?
A:定位不同。zhmm 专注于国密合规 + 本地离线优先 + 中文体验。如果单位有国密要求,或者你只想用一个不需要注册任何账号、不依赖任何云服务的密码管理器,zhmm 很适合。
Q:支持浏览器自动填充吗?
A:目前有一个实验性的 Browser Bridge(基于本地 loopback HTTP + User Script,默认关闭),作为概念验证(POC)。后续计划走 KeePassXC-Browser 协议的稳定路线(X25519 + libsodium + Native Messaging)。
Q:数据安全吗?
A:Argon2id(m=64 MiB)+ SM4-CBC + HMAC-SM3 三重保护。主密码和账号名永不落盘。.zmb 文件自带 HMAC 完整性标签,防篡改防降级攻击。但请用强密码——再好的算法也救不了 123456。
Q:以后会收费吗?
A:GPL-3.0 开源,永远免费。
🚀 快速体验



1 | # 从源码运行 |
首次启动新建密库后,可以直接导入 docs/demo_data.xlsx 里的 15 条演示数据(全假数据)体验完整功能。
数据管理与设置


离线站点词典

🤝 写在最后
zhmm 是一个从实际需求出发、打磨了多个版本的项目。从最初的 PBKDF2 + SM3 到现在的 Argon2id + SM4-CBC + HMAC-SM3,从简陋的界面到现在的多标签/密码历史/TOTP/离线词典……每一行代码都经过反复推敲。
如果你对国密密码管理器感兴趣,欢迎:
- ⭐ Star 关注:github.com/szgenle/zhmm
- 🐛 提 Issue / PR
- 💬 分享给有国密需求的朋友
安全提示:刚开源,建议先在测试环境试用,等经过社区 review 后再用于生产环境。


