Java 程序员第 45 阶段14:网关统一路由大模型接口,配合 Nacos 配置治理,配置加密治理:Nacos配置加密 + Gateway密钥与敏感信息管理

- 为什么大模型网关的配置必须加密
- Nacos 配置加密方案选型
- 接入 Nacos 加密插件实战
- 网关侧密钥管理与动态刷新
- 大模型供应商密钥的安全传递
- 最佳实践与踩坑点总结
1. 为什么大模型网关的配置必须加密

大模型接口对接的是按 token 计费的商业 API(OpenAI、通义、智谱、Claude 等),其 `API Key` 一旦泄露,攻击者可以冒用你的额度产生巨额费用,甚至用你的身份输出违规内容。此外,网关配置里还可能含数据库密码、内部服务 token、灰度白名单等敏感信息。
明文存放在 Nacos 有三大风险:运维同学截图泄露、Nacos 控制台未鉴权被拖库、配置导出文件散落。因此必须把敏感字段**加密存储、解密使用**,且密钥本身不能和密文放在同一处。
2. Nacos 配置加密方案选型

2.1 官方加密插件 nacos-aes-encrypt
Nacos 2.x 官方提供 `nacos-aes-encrypt-plugin`,基于 AES 对称加密。写入时加密、读取时自动解密,对应用透明。缺点是对称密钥若和 Nacos 同机部署仍有泄露面,生产建议密钥来自 KMS。
2.2 应用侧加解密(更可控)
另一种常见做法是:配置在 Nacos 中以密文(如 `cipher:AES:xxxx`)存储,网关启动时或监听时用本地/ KMS 的密钥解密。这种方式解密逻辑在网关侧,密钥可放 KMS,隔离更强。
下表对比:
|
方案 |
加密位置 |
密钥管理 |
应用改动 |
适用 |
|
--- |
--- |
--- |
--- |
--- |
|
Nacos 官方插件 |
Nacos 服务端 |
服务端配置 |
几乎无 |
快速接入 |
|
应用侧解密 |
应用侧 |
KMS/本地 |
需写解密器 |
强合规 |
|
全量 KMS |
不落 Nacos |
KMS |
配置只存引用 |
金融级 |
3. 接入 Nacos 加密插件实战

3.1 服务端启用加密插件
Nacos 服务端 `application.properties` 开启插件并配置密钥(生产改为 KMS 注入):
nacos.core.auth.enabled=true
nacos.plugin.encrypt.version=highest
nacos.plugin.encrypt.aes.secretKey=${NACOS_ENCRYPT_KEY}
客户端在 dataId 内容中以 `cipher` 前缀标记密文,Nacos 控制台显示密文,应用拉取时是明文。
3.2 网关侧自定义解密过滤器(应用侧方案)
当采用应用侧解密,我们实现一个 `ConfigDecryptProcessor`,在配置监听回调里解密:
@Component
public class ConfigDecryptProcessor {
private final KmsClient kmsClient;
public ConfigDecryptProcessor(KmsClient kmsClient) {
this.kmsClient = kmsClient;
}
public String decryptIfNeeded(String raw) {
if (raw != null && raw.startsWith("cipher:AES:")) {
String cipherText = raw.substring("cipher:AES:".length());
String dataKey = kmsClient.getConfigDataKey(); // 从 KMS 取明文密钥
return AesUtil.decrypt(cipherText, dataKey);
}
return raw;
}
}
网关的 `@NacosConfigListener` 拿到原始内容先过一遍 `decryptIfNeeded`,再注入到路由配置,保证内存与运行态是明文、落库是密文。
4. 网关侧密钥管理与动态刷新
4.1 密钥集中管理为 Spring Bean
把解密后的大模型供应商密钥收敛到一个 `LlmCredentialHolder`,由 `@RefreshScope` 管理,配置变更时自动重建:
@RefreshScope
@Component
public class LlmCredentialHolder {
@Value("${llm.qwen.api-key}")
private String qwenApiKey; // 解密后注入
@Value("${llm.zhipu.api-key}")
private String zhipuApiKey;
public String getKey(String provider) {
switch (provider) {
case "qwen": return qwenApiKey;
case "zhipu": return zhipuApiKey;
default: throw new IllegalArgumentException("unknown provider");
}
}
}
4.2 路由转发时注入密钥(不回显)
网关在转发到大模型供应商前,用 `ModifyRequestBodyFilter` 或自定义 `GlobalFilter` 把密钥塞进下游 Header,且**绝不在日志/响应里打印**(用掩码):
@Component
public class LlmAuthInjectFilter implements GlobalFilter, Ordered {
private final LlmCredentialHolder holder;
public LlmAuthInjectFilter(LlmCredentialHolder holder) {
this.holder = holder;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String provider = exchange.getRequest().getHeaders().getFirst("X-Provider");
String apiKey = holder.getKey(provider);
ServerHttpRequest mutated = exchange.getRequest().mutate()
.header("Authorization", "Bearer " + apiKey)
.build();
// 日志仅打印掩码,禁止明文
log.debug("注入 {} 密钥: {}", provider, mask(apiKey));
return chain.filter(exchange.mutate().request(mutated).build());
}
private String mask(String key) {
if (key == null || key.length() < 8) return "***";
return key.substring(0, 4) + "****" + key.substring(key.length() - 4);
}
@Override
public int getOrder() {
return -50;
}
}
5. 大模型供应商密钥的安全传递
5.1 密钥轮换(Rotation)
密钥泄露或定期合规要求轮换时,在 Nacos 把新密钥以密文更新,网关 `@RefreshScope` 自动重建 `LlmCredentialHolder`,无需重启。旧密钥短期内并行保留,确认无流量后再吊销。
5.2 密钥与密文分离存储
|
资产 |
存储位置 |
访问方式 |
|
--- |
--- |
--- |
|
密文配置 |
Nacos(namespace 隔离) |
控制台/API,需鉴权 |
|
数据密钥 |
KMS |
运行时动态获取 |
|
主密钥 |
KMS/HSM |
不落应用 |
这样即便 Nacos 被拖库,攻击者拿到的也只是 AES 密文,没有 KMS 主密钥无法还原。
5.3 审计与最小权限
生产 namespace 开启配置鉴权,只有网关部署账号能读 `LLM_GATEWAY_GROUP`;所有密钥读取走 KMS 审计日志,可追溯谁在何时取了哪个密钥。
6. 最佳实践与踩坑点总结
- **踩坑 1:加密密钥和密文同仓同机**。对称密钥绝不能写在 Nacos 同一份配置里,否则加密形同虚设,务必走 KMS/HSM。
- **踩坑 2:日志打印明文密钥**。务必加掩码工具,且网关 `log` 级别在 prod 设为 INFO,避免 DEBUG 误打密钥。
- **踩坑 3:解密失败无兜底**。KMS 不可用时若直接抛异常会让网关起不来,应加本地缓存密钥 + 降级策略。
- **最佳实践**:敏感配置统一用 `cipher:` 前缀标记,未标记的不允许含密钥(用 CI 扫描拦截)。
- **最佳实践**:密钥轮换常态化,配合第 12 篇的监听热更新做到零停机换密钥。
- **最佳实践**:环境隔离(第 13 篇)+ 配置加密(本篇)组合,是满足等保/合规的最小闭环。
密钥安全是大模型网关的底线,而要让这么多配置与路由「看得见、管得住」,下一站是网关可观测性。
更多推荐




所有评论(0)