数据加密
加密你的 Mix Space
Mix Space 提供了敏感配置的加密存储能力。默认为关。
为什么需要 Key 加密。
假设数据库被脱库。如果开启了 Key 加密,即便攻击者拿到了全部数据,也读不出被标记为加密的字段。同时,也需要谨慎开启此功能——开启后你需要记住加密密钥,否则你将永远丢失这些数据。
开启前请务必备份数据库。忘记密钥 = 这些数据永久无法恢复。
哪些字段会被加密
加密范围不是全部配置项,而是由服务端 schema 上的 encrypt 元数据决定,随版本变化。
判定规则:服务端遍历配置 schema 时,会读每个字段的 encrypt 元数据;父级被标记时,整棵子树都继承加密。绝大多数密码类字段是通过 field.password() / field.passwordHalfGrid() 定义的,这两个 helper 会在构造 schema 时自动注入 encrypt: true,所以你在配置里看到的「密码」输入框,基本都属于加密范围。
当前版本(v14.15.2)覆盖的主要字段:
| 区域 | 字段 |
|---|---|
| OAuth | 各服务商的 client secret、Apple 私钥 |
| 图床 / 对象存储 | S3、R2 的 secretKey |
| 邮件 | Resend API Key、SMTP 密码 |
| AI | 各 Provider 的 apiKey |
| Webhook | 签名密钥 |
| 搜索推送 | 百度推送 Token、Bing API key |
| 会员 | API Key |
| 其他 | 高德地图 Key、设备 Key、Personal Access Token 等 |
想确认当前版本的准确清单,可以看服务端 apps/core/src/modules/configs/ 下的 configs.schema.ts:凡是写成 field.password(...) 或 field.passwordHalfGrid(...) 的字段都会被加密,另加显式标注 { encrypt: true } 的字段。文档这里的说明可能落后于代码,以源码为准。
如何开启
你可以附加 --encrypt_enable 来启动服务。如:
node out/main.mjs --encrypt_enable只要设置了加密密钥而没有显式关闭,加密就会被自动开启。
判定逻辑是ENCRYPT_ENABLE 未设置时,回落到「是否设置了密钥」这一项。也就是说,你只填了密钥、没管开关,加密就已经生效了。如果暂时只想把密钥填进配置、暂不加密,必须显式写 ENCRYPT_ENABLE=false。
指定密钥
可以通过 --encrypt_key <key> 指定,也可以用环境变量。环境变量有两名,MX_ENCRYPT_KEY 优先于 ENCRYPT_KEY:
# 推荐
export MX_ENCRYPT_KEY=<64 位密钥>
# 等价写法
export ENCRYPT_KEY=<64 位密钥>密钥的校验分两层,容易搞混:
| 情况 | 行为 |
|---|---|
| 提供的密钥不是 64 位 | 启动即报错 |
| 提供的密钥短于 64 位 | 不报错,服务端会用 sha256(key + 'mx-encrypt-salt') 派生并补齐到 64 位 |
| 提供的密钥长于 64 位 | 启动即报错 |
| 提供的密钥不是合法 hex 字符 | 启动时不校验,直到真正加解密时才抛出 Invalid key length |
推荐用 openssl rand -hex 32 生成,产出的正是 64 位小写 hex,一次通过全部校验:
openssl rand -hex 32加密算法可用 ENCRYPT_ALGORITHM 调整,默认 aes-256-ecb。
不指定密钥时,服务端默认取机器的 machine-id 并派生。
关闭加密开关不会把已经写入的密文还原成明文。此前加密过的字段会继续以密文形式存储和返回,密文带有 $${mx}$$ 标识前缀。如果你打算关闭加密,需要先准备好原密钥完成解密。
疑难解答
如果出现 Invalid key length,说明你的密钥不是合法的 hex 字符串(长度问题在启动阶段就会被拦下,不会走到这里)。请用 openssl rand -hex 32 重新生成一个 64 位小写 hex 字符串。