内容
<p align="center">
<img src="assets/cryptofort-hero.png" width="200" alt="CryptoFort" />
</p>
<h1 align="center">CryptoFort</h1>
<p align="center">
<b>一个加密存储的凭证库,带有用于代理的MCP服务器。</b>
</p>
<p align="center">
AES-256-GCM加密的密钥,一个可插拔的数据库后端,以及一个默认为只读的<br />
MCP服务器 — 这样代理可以查找凭证而不会有明文接触磁盘的风险。
</p>
<p align="center">
<a href="https://www.npmjs.com/package/cryptofort"><img src="https://img.shields.io/npm/v/cryptofort?style=for-the-badge&color=2563eb&logo=npm&logoColor=white" alt="npm" /></a>
<a href="https://github.com/bradley-t-t/cryptofort/pkgs/npm/cryptofort"><img src="https://img.shields.io/badge/GitHub%20Packages-@bradley--t--t-2563eb?style=for-the-badge&logo=github&logoColor=white" alt="GitHub Packages" /></a>
<img src="https://img.shields.io/badge/license-MIT-2563eb?style=for-the-badge" alt="License" />
<img src="https://img.shields.io/badge/node-%3E%3D20-2563eb?style=for-the-badge" alt="Node >=20" />
<img src="https://img.shields.io/badge/AES--256--GCM-encrypted-1f56cf?style=for-the-badge" alt="AES-256-GCM加密" />
<img src="https://img.shields.io/badge/MCP-ready-3b82f6?style=for-the-badge" alt="MCP就绪" />
</p>
<br />
## 为什么选择CryptoFort
密钥分散在 `.env` 文件、shell 历史记录和明文列中 — 而代理没有安全、结构化的方法来请求它们。CryptoFort 用认证加密密封每个密钥,将密钥完全排除在数据库之外,并为代理提供一个狭窄的MCP接口,默认返回元数据,只有在明确的 `get` 操作时才返回明文。
<table width="100%">
<tr>
<td width="33%" valign="top">
<h3 align="center">静态加密</h3>
<p align="center">每个密钥都用AES-256-GCM加密。主密钥仅存储在环境中,因此数据库转储本身是无用的。</p>
</td>
<td width="33%" valign="top">
<h3 align="center">代理原生</h3>
<p align="center">内置的MCP服务器公开 `search`、`get` 和 `list` — 默认只读,只有在选择时才可写入。</p>
</td>
<td width="33%" valign="top">
<h3 align="center">后端无关</h3>
<p align="center">同一个保险库运行在Supabase、SQLite或任何Postgres上。只需更改一个环境变量即可切换后端。</p>
</td>
</tr>
</table>
<br />
## 安装
```bash
npm install cryptofort
# 加上后端驱动:
npm install @supabase/supabase-js # 或:better-sqlite3 | postgres
```
<details>
<summary>从GitHub Packages安装</summary>
CryptoFort也发布到GitHub Packages,名为 `@bradley-t-t/cryptofort`。将 `@bradley-t-t` 作用域指向GitHub注册表,并使用具有 `read:packages` 权限的令牌进行身份验证 — GitHub Packages即使对于公共包也需要身份验证:
```ini
@bradley-t-t:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
```
```bash
npm install @bradley-t-t/cryptofort
```
</details>
## 库的使用
```ts
import { Vault, Crypto, SqliteAdapter } from 'cryptofort';
const adapter = new SqliteAdapter('vault.db');
await adapter.init();
const vault = new Vault({
adapter,
crypto: new Crypto({ key: process.env.CRYPTOFORT_MASTER_KEY! }),
});
await vault.put({
name: 'stripe-secret-key',
secret: 'sk_live_…',
provider: 'stripe',
tags: ['payments'],
});
await vault.search('stripe'); // 仅元数据 — 永远不会是密钥
await vault.get('stripe-secret-key'); // 解密后的密钥
```
生成主密钥(base64,32字节):
```bash
node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
```
… 或使用 `import { generateKey } from 'cryptofort'` 从库中生成。
## MCP服务器
将任何MCP客户端指向 `cryptofort-mcp` 二进制文件:
```json
{
"mcpServers": {
"cryptofort": {
"command": "cryptofort-mcp",
"env": {
"CRYPTOFORT_ADAPTER": "supabase",
"SUPABASE_URL": "https://<ref>.supabase.co",
"SUPABASE_SERVICE_ROLE_KEY": "<service-role-key>",
"CRYPTOFORT_MASTER_KEY": "<base64-32-bytes>"
}
}
}
}
```
服务器默认 **只读**。添加 `"args": ["--allow-write"]` 以公开 `credential_put`。
### 工具
| 工具 | 访问权限 | 描述 |
| :------------------ | :----- | :-------------------------------------------------------------------- |
| `credential_search` | 读取 | 按名称、描述、提供者或标签搜索。仅返回元数据。 |
| `credential_get` | 读取 | 解密并返回单个密钥,精确按名称。 |
| `credential_list` | 读取 | 在命名空间中列出凭证元数据,可选按标签过滤。 |
| `credential_put` | 写入 | 创建或更新凭证。需要 `--allow-write`。 |
### 环境
| 变量 | 是否必需 | 目的 |
| :------------------------------------------- | :------- | :---------------------------------------------------------- |
| `CRYPTOFORT_MASTER_KEY` | 是 | base64,32字节的AES-256密钥。永远不会写入数据库。 |
| `CRYPTOFORT_ADAPTER` | 否 | `supabase`(默认),`sqlite` 或 `postgres`。 |
| `CRYPTOFORT_KEY_ID` | 否 | 密钥标识符,用于轮换。默认为 `default`。 |
| `SUPABASE_URL` / `SUPABASE_SERVICE_ROLE_KEY` | Supabase | Supabase适配器的连接。 |
| `CRYPTOFORT_POSTGRES_URL` | Postgres | Postgres适配器的连接字符串。 |
| `CRYPTOFORT_SQLITE_PATH` | 否 | SQLite文件路径。默认为 `cryptofort.db`。 |
## 后端
| 后端 | 驱动 | 最适合 |
| :----------- | :---------------------- | :-------------------------------------------------------- |
| **Supabase** | `@supabase/supabase-js` | 已托管,跨代理共享,服务角色访问。 |
| **Postgres** | `postgres` | 将保险库放入现有的Postgres基础设施中。 |
| **SQLite** | `better-sqlite3` | 本地,单进程,零基础设施使用。 |
## 工作原理
- 只有密钥是密文。`name`、`description`、`provider` 和 `tags` 保持明文,因此搜索和列表功能无需解密即可工作。
- 每个密钥都用 **AES-256-GCM** 加密 — 认证加密,因此任何篡改在读取时都会被捕获。
- **主密钥从不接触数据库**。它仅存在于 `CRYPTOFORT_MASTER_KEY` 中;被盗的转储在没有它的情况下揭示了什么都没有。
- MCP服务器除非使用 `--allow-write` 启动,否则拒绝写入,因此代理可以查找密钥但不能悄悄地重写保险库。
## 架构
参见 [`sql/001_cryptofort_credentials.sql`](sql/001_cryptofort_credentials.sql) — 一个表,一列密文,其余是用于搜索的明文元数据。
## 开发
```bash
npm run build # 使用tsup打包
npm test # 运行vitest套件
npm run typecheck # tsc --noEmit
```
## 许可证
在MIT许可证下发布。
<br />
<p align="center">
<sub>静态加密的密钥 — 交给代理,绝不泄露。</sub>
</p>