最近用 AI Agent 辅助完成了一个纯本地密码管理器(代号"灵钥 LingKey")的完整方案设计,从需求规格到架构设计再到多端扩展,沉淀了一些架构层面的思考,记录下来供参考。
一、为什么做纯本地密码管理器 现有密码管理器多为云端订阅制,用户对"数据上云"存在顾虑。核心设计目标就三条:集中记录、快速检索、全程本地 AES-256 加密不上传。
二、分层架构设计 采用经典分层架构 + 服务化,UI 与业务逻辑解耦: 表现层(PyQt6):登录页 / 主列表 / 编辑弹窗 / 设置页 应用服务层:VaultService / RecordService / TagService / BackupService / LockManager 领域安全层:CryptoService / PasswordToolkit / 实体模型 数据访问层:RecordRepository / TagRepository 存储层:SQLite(vault.db)/ config.json / 加密备份文件 这样分层的收益是:核心加密逻辑与 UI 完全解耦,便于单元测试,也便于后续替换前端(比如换成 Flutter 做移动端)。
三、加密方案(核心) 密钥派生用 Argon2id,加密用 AES-256-GCM:
from argon2.low_level import hash_secret_raw, Type
key = hash_secret_raw(
secret=master_password.encode(),
salt=salt,
time_cost=3,
memory_cost=65536, # 64MB
parallelism=4,
hash_len=32,
type=Type.ID
)
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
aesgcm = AESGCM(key)
nonce = os.urandom(12)
ciphertext = aesgcm.encrypt(nonce, plaintext, None)
四、三个关键设计点:
- 密码字段密文入库,明文零落盘;
- 解锁时派生密钥,锁定时立即清零内存;
- 数据库写入用事务,避免异常退出的半写状态。 四、数据模型 核心是 records / tags / record_tags / vault_meta 四张表,敏感字段(url、username、notes)加密存储,password 单独存密文 + IV:
CREATE TABLE records (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
type TEXT NOT NULL,
url_or_path TEXT,
username TEXT,
password_enc BLOB NOT NULL,
password_iv BLOB NOT NULL,
notes_enc BLOB,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
deleted_at TEXT
);
五、多端扩展:一核一密多壳 这是设计中最有意思的部分。跨多端做密码管理器,最容易犯的错是"每端各写一套",导致加密格式不一致。我的思路是:
- 一核:定义与语言无关的《加密容器格式规范》,所有端严格按同一规范实现;
- 一密:用户只有一个主密码,多端同步的永远是密文,密钥不出设备(端到端加密);
- 多壳:UI 和系统集成用各端原生壳实现。 各端选型:iOS/Android 用 Flutter(~90% 复用),鸿蒙必须用 ArkTS 原生(不兼容 APK),浏览器插件用 WebExtension。 一个关键认知转变:移动端"搜集"模式从 PC 的"我去读别人"反转为"别人来问我"(系统级 AutoFill),这也是 1Password/Bitwarden 在手机上的工作方式。 六、小结 纯本地密码管理器的架构核心是"加密分层 + 密钥生命周期管理 + 多端格式统一"。本次方案设计过程中,我用 AiPy 辅助完成了文档产出与架构梳理,但加密方案与数据模型的关键决策仍然自己把关。