Skip to content

凭据加密(KEK → DEK)

Reeve 的凭据库用 AES-256-GCM 加密,密钥(DEK)放在 OS 钥匙串。可选启用「主密码」后,DEK 再被 Argon2id KEK 包装一层 —— 磁盘 + keyring 同时被偷也开不了。

两种模式

模式 A:基础模式(无主密码)

凭据明文
   │ AES-256-GCM (key = DEK)

密文 → SQLite 数据库

DEK → 直接存 OS keyring(明文)
  • 安全等级:SSH 客户端业界平均水平
  • 解锁:应用启动自动从 keyring 拉 DEK
  • 攻击者拿到磁盘 + keyring 即可开

模式 B:有主密码(推荐)

用户主密码
   │ Argon2id(m=19MiB, t=2, p=1, OWASP 推荐)

KEK
   │ AES-256-GCM 包装

Wrapped DEK → 存 OS keyring

凭据明文
   │ AES-256-GCM (key = DEK)

密文 → SQLite 数据库
  • 安全等级:完整密码学屏障
  • 解锁:应用启动 locked,等用户输主密码 → Argon2 派生 KEK → 解开 Wrapped DEK → DEK 进内存
  • 攻击者拿到磁盘 + keyring 还需要爆破主密码,Argon2id 参数让单次尝试 ~2 秒,强密码下不可行
  • 空闲超时锁定:DEK 缓存清零,需重新输主密码

AES-256-GCM 细节

每条加密字段(password_enc / privkey_enc / vault.value_enc 等):

base64( nonce[12] || ciphertext+tag[16] )
  • Nonce 每次加密随机生成(96 位)
  • 认证标签 16 字节(防篡改)
  • aes-gcm-siv crate(更抗 nonce 误用)

OS keyring 集成

平台后端
WindowsCredential Manager (wincred)
macOSKeychain (security framework)
LinuxSecret Service(GNOME Keyring / KWallet)/ libsecret

存储 key:com.agilefr.reeve.dek(基础模式)或 com.agilefr.reeve.wrapped-dek(主密码模式)。

Linux 注意

Linux 上如果没装 Secret Service(如 SSH 远端裸 server),Reeve 会回落到加密文件(<app data>/secrets.enc),用机器 ID 派生 key。安全等级低于桌面 GUI 环境,仅作 fallback。

主密码设置

设置 → 主密码与应用锁定

启用主密码

  1. 设置主密码
  2. 输入主密码 + 确认
  3. 后端:
    • 派生 KEK(Argon2id)
    • 用 KEK 包装现有 DEK
    • Wrapped DEK 覆盖 keyring
    • 删除明文 DEK
  4. 完成 → 应用现在处于 locked-on-startup 模式

修改主密码

需要先输入当前主密码 + 新主密码(×2):

  1. 旧主密码 → 派生旧 KEK → 解出 DEK
  2. 新主密码 → 派生新 KEK → 重新包装 DEK
  3. 覆盖 keyring

关闭主密码

需输入主密码:

  1. 派生 KEK → 解出 DEK
  2. 直接把明文 DEK 写 keyring(去掉 Wrapped 层)
  3. 回到基础模式

解锁流程

应用启动时:

1. 读 keyring,得到 DEK 或 Wrapped DEK
2. 如果是 DEK:直接进 unlocked
3. 如果是 Wrapped DEK:进 locked 屏幕
   ├── 显示 UnlockScreen(输密码框)
   ├── 用户输主密码
   ├── 派生 KEK,尝试解开 Wrapped DEK
   ├── 成功:DEK 进内存,unlocked
   └── 失败:限流(3 次错误锁 10s,10 次错误锁 5min)

锁定时哪些操作受影响

操作锁定时行为
查看服务器列表(仅元数据)✅ 可用
测试连接 / 终端 / SFTP❌ 拒绝(需 DEK 解凭据)
凭据 Reveal / 敏感库 Reveal❌ 拒绝
MCP 工具调用(含所有 AI 操作)❌ 拒绝
审计查看✅ 可用
配置查看✅ 可用
配置修改(含主密码改)❌ 拒绝

UnlockScreen 实测覆盖 38 个守护 Command + UI 闸门 + safeInvoke 全局拦截器,确保锁定时凭据相关功能彻底关停。

空闲自动锁定

设置 → 主密码与应用锁定

  • 默认关闭
  • 可设 5 / 10 / 15 / 30 / 60 分钟
  • 鼠标 / 键盘活动重置计时
  • 到时间 → DEK 缓存清零 → 显示 UnlockScreen

重置凭据库

设置 → 主密码 → 高级 → 重置凭据库

选项说明
重新加密生成新 DEK + 用新 DEK 重加密全部凭据(中毒恢复)
彻底清空删除所有凭据 + DEK;服务器 / 敏感库 / 审计保留

二次确认 + 主密码验证。

实际安全等级

攻击场景基础模式主密码模式
偷磁盘DEK 在 keyring 没拿到,密文无用同上
偷磁盘 + keyring暴露(DEK 是明文)不暴露(DEK 被 KEK 包装,需爆破主密码)
RAM 取证(应用解锁状态)DEK 在内存DEK 在内存
RAM 取证(应用锁定状态)DEK 在 keyringKEK 已清零,需重输主密码
键盘记录主密码捕获即可(但用户没设)主密码被记录 → 加上磁盘 + keyring 才能解

主密码忘了

没有恢复机制——这是设计:

  • 重置凭据库 → 全部凭据丢失(但服务器列表 / 审计保留)
  • 你需要重新添加所有服务器的凭据

不允许「邮件找回」「密保问题」等弱机制,因为那些都是潜在攻击面。

不建议的做法

  • ❌ 主密码用 123456 / qwerty
  • ❌ 主密码写在 sticky notes 贴电脑上
  • ❌ 把整个 <app data>/com.agilefr.reeve/ 同步到 OneDrive / 网盘(密文不算泄漏,但凑全 keyring 就是泄漏)
  • ❌ 在企业域机器上不设主密码(IT 可读 keyring)

下一步

受控的远程运维助手 — 让 AI 安全地帮你管服务器