Repository navigation
Conversation
服务商配置(内含用户填写的模型 API Key)落库前会加密,但密钥硬编码在源码中:
private static final String SECRET_KEY = "1234567890123456";
Cipher.getInstance("AES"); // 默认 ECB 模式
本仓库是公开的,密钥等同公开信息——加密实际形同虚设。任何拿到数据库内容的人
(备份泄露、注入、云快照、运维越权)都能解出全部用户的模型服务商 API Key。
新增 ConfigCrypto 替代原实现:
- 密钥来自环境变量 CONFIG_ENCRYPTION_KEY,缺失时启动即失败,不提供任何默认值
- 若把该变量设为旧的泄露密钥,同样启动失败,避免"改了配置但没换密钥"
- AES/GCM/NoPadding,每条记录随机 12 字节 IV,128 位认证标签
- 密文格式 v2: + Base64(IV ‖ 密文+标签)
- 不带前缀的旧密文仍可解密,写入时一律转新格式,存量数据随使用逐步迁移
- 新增 ConfigCryptoInitializer 在启动阶段主动校验,避免故障延迟到业务链路才暴露
- 新增 ConfigCryptoMigration,设 CONFIG_CRYPTO_MIGRATE=true 可一次性迁移存量数据
同时清理:
- 删除 ConfigEncryptor(零调用死代码,同样硬编码密钥 "AgentX-Config-Key")
- 删除 ValidationUtils.EncryptUtils,加密实现收敛为一套
- 修复 ProviderConfigConverter.getNullableResult(ResultSet, int) 直接返回 null 的
未实现分支——该路径此前会静默拿到空配置而非报错
新增本仓库的第一个测试 ConfigCryptoTest(9 个用例),锁定的是安全属性而非实现细节:
密钥必须来自外部注入、相同明文不得产生相同密文、密文被篡改必须失败、换密钥解不出、
缺密钥必须报错、拒绝沿用泄露密钥、旧格式仍可读、新写入一律新格式、null 与空串不抛异常。
CI 相应增加 mvn test 步骤,否则这些约束无人守护。
⚠️ 部署前必须先在服务器 .env 配置 CONFIG_ENCRYPTION_KEY,否则后端起不来。
⚠️ 加密方式的修复不会让已泄露的密钥重新安全——存量 API Key 应视为已泄露,
需通知用户轮换。
验证:mvn test 全部通过(9/9);spotless 格式化通过;文档链接校验 167 条全部有效。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
合并这个 PR 会触发自动部署,而新代码要求服务器上必须有
CONFIG_ENCRYPTION_KEY,否则后端起不来。请先在服务器上执行:
确认
.env里有这一行之后,再合并。问题
服务商配置(内含用户填写的模型 API Key)落库前会加密,但密钥硬编码在源码里:
本仓库是公开的,密钥等同公开信息 —— 加密实际形同虚设。 任何拿到数据库内容的人(备份泄露、SQL 注入、云快照、运维越权)都能解出全部用户的模型服务商 API Key。
修复
新增
ConfigCrypto替代原实现:CONFIG_ENCRYPTION_KEY,缺失即启动失败密文格式
v2:+ Base64(IV ‖ 密文+标签)。不带前缀的旧密文仍可解密,写入时一律转新格式,因此存量数据会随使用逐步迁移。另外两处防呆:
ConfigCryptoInitializer在启动阶段主动校验,让配置缺失在启动时暴露,而不是等某个用户第一次读写服务商配置时才炸CONFIG_ENCRYPTION_KEY误设为旧的泄露密钥,同样启动失败顺带清理
ConfigEncryptor—— 零调用死代码,同样硬编码密钥"AgentX-Config-Key",留着容易被误用ValidationUtils.EncryptUtils,加密实现收敛为一套ProviderConfigConverter.getNullableResult(ResultSet, int)直接return null的未实现分支 —— 该路径此前会静默拿到空配置而非报错本仓库的第一个测试
ConfigCryptoTest9 个用例,锁定的是安全属性而非实现细节:CI 相应增加
mvn test步骤 —— 否则这些约束没人守。合并后还要做两件事
① 迁移存量数据
读取兼容旧格式、写入才转新格式,所以不活跃的记录会长期以旧格式留存:
迁移全部完成后,可以删掉
ConfigCrypto.decryptLegacy(),彻底断开对旧密钥的依赖。② 通知用户轮换 API Key
加密方式修好了不等于旧密钥安全了 —— 那把密钥早已随公开仓库外泄。存量 API Key 应视为已泄露。
验证
mvn test9/9 通过spotless格式化通过🤖 Generated with Claude Code