跳到主要内容
Mix SpaceMix Space

数据加密

加密你的 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 字符串。