本

本地 DPAPI 免口令凭据库(Windows)

作者:注册老炮@MedXpert I SynomosAIv1

用 Windows DPAPI 把密钥/口令加密存到本机、仅当前用户可解、明文不落盘、带权限锁与泄漏标注的可复用凭据保管 skill。适合"当前 Windows 账号即信任边界"的本地保管场景。

下载量
273
点赞
67
价格
免费

技能文档

---
name: dpapi-local-vault
slug: dpapi-local-vault
displayName: 本地 DPAPI 免口令凭据库(Windows)
description: 用 Windows DPAPI 把密钥/口令加密存到本机、仅当前用户可解、明文不落盘、带权限锁与泄漏标注的可复用凭据保管 skill。适合"当前 Windows 账号即信任边界"的本地保管场景。
version: "1.1.0"
license: MIT
platforms: [Windows]
author: 潘布达 (Buda Pan) @SynomosAI
category: it-ops-security
tags: [凭据管理, DPAPI, 本地加密, 免口令, Windows, 密钥保管]
agent_created: true
title: 本地 DPAPI 免口令凭据库(Windows)
display_name: 本地 DPAPI 免口令凭据库(Windows)
---

# 本地 DPAPI 免口令凭据库(Windows)

## 何时用
- 需要在**本机**安全保管一把密钥/口令(如云 API 密钥对、token),且信任边界就是"当前 Windows 登录用户"。
- 想要**免口令**体验:DPAPI 由系统用当前用户凭据透明加解密,无需记忆主口令。
- 不想把明文写进任何文件/日志/云文档;落盘只有 DPAPI 密文 + base64 封装。
- 需要给凭据打**泄漏标注**(如"已在聊天明文暴露、待轮换"),供后续取用前警告。

## 何时不用
- 跨设备/跨账号同步 → 用 `unified-credential-vault`(带主口令、可恢复、全生态同读)。
- 需要多人共享或换机可解 → DPAPI 绑定本机本用户,换机/换账号解不开。
- 极高密级且担心"同账号被拖" → DPAPI 仅防其他用户/其他机,同账号可读,应上主口令保险库。

## 用法
默认保险库目录:`~/.ucvault_local`(即 `C:\Users\<你>\.ucvault_local`)。

### 推荐入口:key_drop.py(密值不进命令行、不进历史)
`~/.ucvault_local/tools/key_drop.py`。三种模式,都不把密值写进命令行参数:

```bash
# 1) 单值,隐藏输入(Git Bash / 支持 tty 的终端)
python ~/.ucvault_local/tools/key_drop.py hunyuan_api_key

# 2) 成对密钥对(如云 SecretId + SecretKey)
python ~/.ucvault_local/tools/key_drop.py tencent_cos --pair

# 3) 记事本模式(最保险,任何终端都能用,密值走 GUI 不经过终端)
python ~/.ucvault_local/tools/key_drop.py tencent_cos --pair --notepad
```

- **模式 3 是最稳的**:不依赖终端能力,密值只经过记事本,导入后临时文件立即删除。
  终端不支持隐藏输入、或旁边有人/在录屏时,一律用它。
- `vault put <label>`(vault.py 自带)只能存**单值**,存不了 SecretId+SecretKey 成对——成对请用 key_drop `--pair`。
- ⚠️ 坑:`getpass.getpass()` 在**无 tty** 环境(管道、CI、部分 Windows 终端)不会抛异常,
  而是挂等 `/dev/tty` 导致命令卡死。先判 `sys.stdin.isatty()` 再决定走 getpass,
  否则退回 `stdin.readline()` 并明确警告用户"输入会显示"。

### 兜底:直接调 store_secret.py(heredoc)
⚠️ heredoc 里的密值会进终端回滚缓冲区与屏幕,仅在无法用 key_drop 时采用:

```bash
python store_secret.py tencent_cos --scope secret --notes "腾讯云COS" \
  --exposed --exposed-where "WorkBuddy聊天" --exposed-at "2026-08-28" <<'EOF'
AKIDxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxKEY
EOF
# 两行 = 密钥对(SecretId / SecretKey);单行 = 单值
# 输出 STORED_OK 即成功(回环校验通过,不打印明文)
```
- 落盘:`~/.ucvault_local/<label>.enc`(DPAPI 密文)+ `<label>.meta.json`(作用域/泄漏标注)。
- 权限:`icacls /inheritance:r /grant:r <USER>:F` + `chmod 600`,仅当前用户可读。

### 取回
```bash
python get_secret.py tencent_cos             # 默认隐藏密值(安全展示)
python get_secret.py tencent_cos --show      # 显示明文(格式化输出,带 value:/secret_id: 标签前缀)
python get_secret.py tencent_cos --raw       # 只输出裸值(脚本/管道用,2026-09-07 新增)
```

⚠️ **前缀坑(2026-09-07 实测教训)**:`--show` 输出是带 `value: ` / `secret_id:`
标签前缀的**格式化文本**,整段当令牌塞进 HTTP 头/URL,会得到大面积 401/40013
"令牌失效"假象——令牌其实是好的。**脚本取值一律用 `--raw`**;用 `--show` 必须
`sed -n 's/^value: *//p'` 截掉前缀。任何工具的人类可读输出都不能直接当凭据用。

## 安全要点(落地约束)
- **明文零落盘**:密钥只在 `CryptUnprotectData` 解密后的内存里短暂存在;文件里永远是 DPAPI 密文。
- **不回显**:`get_secret.py` 默认隐藏密值,`--show` 才显;store 的回环校验不打印明文。
- **密钥不进命令行**:密值走 stdin(heredoc),绝不用命令行参数传,防 `ps`/历史泄漏。
- **权限锁当前用户**:写入后立即去继承 + 仅授权当前用户完全控制。
- **泄漏标注**:`--exposed` 会在 meta.json 写 `EXPOSED_PENDING_ROTATION` + 暴露位置/时间,取用前先看到警告。

## 配套文件
- `store_secret.py` — 加密写入(读 stdin;两行=密钥对,单行=单值;可选泄漏标注)。
- `get_secret.py` — 解密取回(默认隐藏密值,`--show` 才显明文)。
- `tools/key_drop.py` — **推荐投递入口**:隐藏输入 / 成对 / 记事本三种模式。
- `vault.py` / `vault.cmd` — 薄封装(`put`/`get`/`list`/`rm`);`put` 仅支持单值。

## 应用侧读取约定(三级兜底)
应用不要自己解析 `.enc`,统一按此优先级取,改轮换只需换源头、不动代码:

```
1. 环境变量          服务器部署 / CI
2. 本机保险库        ~/.ucvault_local(DPAPI)
3. 项目内文件        .llm_key / .cos.conf(仅兜底)
```

参考实现见 `medxpert-reg-mcp/cred.py`(`llm_key()` / `cos_cred()`,通过
`get_secret.py --show` 取字段,只取长度/布尔判断,绝不打印密值)。
要点:取密值的代码**永远不要 print 密值**,也不要把它写进日志或异常信息。

## 真实案例
本机保险库 `~/.ucvault_local/tencent_cos.enc`(Windows 即 `%USERPROFILE%\.ucvault_local\tencent_cos.enc`)即此法保管的一把腾讯云 COS 密钥(root 级,已标注 EXPOSED_PENDING_ROTATION,待用户在 CAM 禁用/轮换)。

---

## 退出码与错误输出
| 场景 | 输出 | 退出码 | 处置 |
|---|---|---|---|
| 取回时 label 不存在 | `NOT_FOUND: <vault路径>` | 2 | 先用 store_secret.py 写入,或核对 label 拼写 |
| 写入时 stdin 为空 | `MISSING_INPUT` | 2 | 检查管道输入:两行 = id+key,一行 = 单值 |
| 跨机器/换用户解密失败 | DPAPI 异常(非零退出) | ≠0 | DPAPI 绑定当前 Windows 用户+机器;跨机需提前导出,未导出不可恢复(设计内行为) |
| --show 与 --raw 混淆 | --show 输出带 `value: ` 前缀(人读格式) | 0 | 脚本取值必须用 `--raw`(裸值),禁止对 --show 输出做字符串截取 |
## 反模式 FAQ
**Q:换电脑/重装系统后解不开了,是 bug 吗?**
不是,是设计内行为。DPAPI 绑定当前 Windows 用户+机器;跨机迁移必须提前导出,没导出就不可恢复。

**Q:能把保险库目录放进网盘同步吗?**
密文 blob 可以同步做灾备存档,但跨机器解不开(见上条)。别指望网盘当跨机传输通道。

**Q:--show 输出直接给脚本解析为什么出错?**
--show 是人读格式,带 `value: ` 前缀;脚本取值必须用 --raw。禁止对 --show 输出做字符串截取。

**Q:多脚本并发读写同一凭据安全吗?**
读操作无竞争;写操作(store/rotate)要串行,轮换时先禁用旧 key 再写入新 key。
## 版权与许可

- © 2026 SynomosAI。本技能按 MIT 许可证开源(见 LICENSE.md);软件依 LICENSE 使用,零数据收集。
- **知识版权声明**:本作品汇集的方法论、协议流程与结构化知识,其编排与原创表达归 SynomosAI 所有;未经书面许可,不得复制、转载、摘编、转售或用于训练任何模型 / 商业系统。
- **免责声明**:本作品按「现状」(AS IS)提供,不提供任何明示或暗示担保;使用风险由使用者自行承担,因使用所致任何损失作者不承担责任。
## 安装与使用矩阵
| 宿主 | 安装位置 | 方式 |
|---|---|---|
| Claude Code / CodeBuddy | `~/.claude/skills/dpapi-local-vault/` | 复制本目录即可 |
| OpenCode | `~/.config/opencode/skills/dpapi-local-vault/` | 复制本目录即可 |
| 通用 Agent Skill 加载器 | `~/.agents/skills/dpapi-local-vault/` | 复制本目录即可 |
---

[![LGD-Powered · 凡自治之物](https://medxpert.cn/badge/powered/svg/lgd-powered-cn.svg)](https://medxpert.cn)

> © 2026 SynomosAI(诺声 Logos 署名体系)· MIT License · 按现状(AS IS)提供,不作任何明示或暗示担保

如何安装此技能?

访问技能市场,点击「安装」按钮,按提示将技能包放入 AI 编程助手的 skills 目录即可。

浏览技能市场

支持平台:Qoder · QoderWork · Claude · Codex 等 AI 编程助手

本地 DPAPI 免口令凭据库(Windows) - 免费 | 技能派