Craft Agents 凭据安全设计:AES-256-GCM 加密存储全流程解析
【免费下载链接】craft-agents-oss项目地址: https://gitcode.com/GitHub_Trending/cr/craft-agents-oss
Craft Agents 是一款开源的 AI Agent 开发工具,它的凭据安全设计值得所有工具开发者借鉴:所有 API 密钥、OAuth 令牌等敏感凭据,都通过AES-256-GCM 认证加密写入本地加密文件~/.craft-agent/credentials.enc,加密密钥则由操作系统级硬件指纹经PBKDF2派生而来。本文带你从零看懂这套凭据加密存储的完整流程——不需要密码学背景,也能理解它的每一道安全防线 🔐
一、为什么凭据安全是 AI 工具的必修课
使用 AI Agent 工具时,你总要提供"钥匙":Anthropic 的 API Key、ChatGPT 的 OAuth 令牌、AWS 的 IAM 密钥、Telegram 机器人令牌……一旦这些凭据以明文躺在磁盘上,任何能读取你文件的程序都能"冒充"你的账号。
Craft Agents 的方案可以概括为一句话:凭据加密存储 + 机器绑定密钥 + 完整性校验,三者缺一不可。
二、凭据都有谁:12 种敏感凭据的统一管理
在 types.ts 中定义了全部 12 种凭据类型,覆盖四大场景:
| 场景 | 凭据类型 | 典型例子 |
|---|---|---|
| 全局认证 | anthropic_api_key、claude_oauth | Claude 订阅 OAuth 令牌 |
| LLM 连接 | llm_api_key、llm_oauth、llm_iam、llm_service_account | 各家模型 API Key、AWS/GCP 密钥 |
| 工作区与数据源 | workspace_oauth、source_oauth、source_bearer、source_apikey、source_basic | MCP 服务器、数据库连接 |
| 消息网关 | messaging_bearer | Telegram Bot Token |
每个凭据用类型::作用域的键名唯一定位,例如llm_api_key::openai-default、source_oauth::ws-123::github。这里有个小细节:分隔符特意选用::而不是/,因为 URL 和服务器名称里经常出现斜杠,用双冒号可以彻底避免冲突(见 types.ts 第 171-207 行)。
💡 统一的键名体系,让"取哪把钥匙"变成了纯粹的字符串拼接,加密层无需感知业务细节。
三、加密核心:AES-256-GCM 到底加密了什么
AES-256-GCM 是当今最主流的认证加密模式,它同时提供两样东西:
- 机密性:256 位密钥的 AES,密文无法还原出明文;
- 完整性:GCM 模式会额外生成 16 字节的Auth Tag(认证标签),密文被篡改哪怕 1 个比特,解密时都会直接失败。
这意味着 Craft Agents 的凭据文件不仅"看不见",而且"改不动" 👍
加密文件的二进制布局在 secure-storage.ts 第 15-24 行 的文件头注释中完整定义:
[文件头 - 64 字节] ├── Magic: "CRAFT01\0"(8 字节,魔数校验) ├── Flags: 4 字节(保留) ├── Salt: 32 字节(PBKDF2 随机盐) └── 保留: 20 字节 [加密载荷] ├── IV: 12 字节(每次写入随机生成) ├── AuthTag: 16 字节(GCM 认证标签) └── 密文: 变长(加密后的 JSON 凭据库)常量定义见 secure-storage.ts 第 48-58 行。
四、密钥从哪来:硬件指纹 + PBKDF2 密钥派生
这是整个设计最精妙的部分:加密密钥从不保存在磁盘上,也从不让你输入。它从"这台机器独有的指纹"推导而来。
getStableMachineId() 函数(第 65-99 行) 在三大平台各取最稳定的标识:
- macOS:
IOPlatformUUID(绑定逻辑主板,终身不变) - Windows:注册表
MachineGuid(安装系统时生成) - Linux:
/var/lib/dbus/machine-id
随后在 getEncryptionKey()(第 319-333 行) 中完成密钥派生:
机器指纹 --SHA-256--> 加盐材料 --PBKDF2-SHA256 (10万次迭代)--> 32字节 AES-256 密钥为什么这样做很稳?
- 10 万次 PBKDF2 迭代把密钥拉伸到计算上难以暴力破解的程度(
PBKDF2_ITERATIONS = 100000); - 硬件指纹"稳如磐石"——早期版本曾用主机名派生密钥,但 DHCP 换名就会导致凭据全部"变砖",v2 方案彻底修复了这个问题;
- 旧数据自动迁移:loadStoreSync()(第 198-256 行) 会先尝试新密钥,失败再尝试 v1 旧密钥,成功即用新密钥重新加密回写,用户无感完成升级。
⚠️ 代价是:凭据文件绑定当前机器。把
credentials.enc拷到别的电脑无法解密——这恰恰是一种安全特性。
五、写入与读取全流程
写入流程(saveStoreSync(),第 281-317 行):
- 目录不存在则以
0700权限创建~/.craft-agent/; - 序列化整个凭据库为 JSON(含版本号、创建/更新时间戳);
- 每次写入都随机生成新的 12 字节 IV——这是 GCM 安全的硬性要求;
- AES-256-GCM 加密,取出 16 字节 Auth Tag;
- 拼装"文件头 + IV + Auth Tag + 密文",以
0600权限(仅属主可读写)落盘。
读取流程则相反:校验魔数 → 读取盐值 → 派生密钥 → 用 IV 和 Auth Tag 解密 → 解析 JSON。任何一步失败都说明文件已损坏或被篡改。
六、容错与自愈:文件损坏了怎么办?
工程师没有止步于"加密",还做足了异常处理:
- 最小长度校验:文件短于"头部+IV+标签"直接判定损坏;
- 双密钥尝试:新旧密钥都失败才确认损坏,避免误删;
- 损坏自愈:handleCorruptedFile()(第 350-362 行) 会删除坏文件并清空缓存,程序回到"未配置"的干净状态,提示你重新认证即可;
- 启动体检:CredentialManager.checkHealth()(manager.ts 第 629-699 行) 在应用启动时主动触发一次完整解密,区分"文件损坏"与"机器迁移导致解密失败",给出友好提示而不是让用户撞上晦涩报错;
- 过期感知:isExpired()(manager.ts 第 596-612 行) 提前 5 分钟判定 OAuth 令牌过期,且对"缺少过期时间"的令牌采取"宁可按过期处理"的保守策略。
七、常见问题 FAQ
问:为什么不用系统钥匙串(Keychain)?答:Craft Agents 选择自研加密文件,是为了跨三平台行为完全一致,且免去认证弹窗,保证 CLI、桌面端、无头服务器体验统一。代价是没有系统级熵源,因此用硬件指纹 + PBKDF2 补齐。后端接口设计在 backends/types.ts,理论上可随时插入新后端,按优先级自动排序(当前环境变量后端已被主动禁用,强制手动录入凭据)。
问:0600 权限意味着什么?答:POSIX 文件权限,只有你的用户账号能读写这个文件,其他用户(包括同机他人)一律拒绝访问,是加密之外的第二道防线。
问:密钥存在哪里?答:哪儿都不存在。每次启动从硬件指纹 + 文件内盐值现算,内存中使用完即弃,磁盘上不留任何密钥痕迹。
问:如何彻底清除凭据?答:删除~/.craft-agent/credentials.enc即可,代码层面也可调用 manager.delete() 按类型精确移除。
小结
Craft Agents 的凭据安全设计是一条完整闭环:
12 种凭据统一建模 → AES-256-GCM 认证加密 → 硬件指纹 + PBKDF2 派生密钥 → 0600 权限落盘 → 双密钥迁移 → 损坏自愈 → 启动体检
对普通用户而言,你只需正常填入 API Key;对安全而言,每一层都在默默工作。这套 credentials 模块(核心约 1200 行)堪称中小型项目凭据存储的参考实现,值得收藏研究 📚
【免费下载链接】craft-agents-oss项目地址: https://gitcode.com/GitHub_Trending/cr/craft-agents-oss
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考