Dev Crypto (#730)

* feat: remove admin mode

* feat: bugfix

* feat(crypto): 添加RSA-OAEP + AES-GCM混合加密服务

- 实现CryptoService加密服务,支持RSA-OAEP-2048 + AES-256-GCM混合加密
- 集成数据库层加密,自动加密存储敏感字段(API密钥、私钥等)
- 支持环境变量DATA_ENCRYPTION_KEY配置数据加密密钥
- 适配SQLite数据库加密存储(从PostgreSQL移植)
- 保持Hyperliquid代理钱包处理兼容性
- 更新.gitignore以正确处理crypto模块代码

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(scripts): 添加加密环境一键设置脚本

- setup_encryption.sh: 一键生成RSA密钥对+数据加密密钥+JWT密钥
- generate_rsa_keys.sh: 专业的RSA-2048密钥对生成工具
- generate_data_key.sh: 生成AES-256数据加密密钥和JWT认证密钥
- ENCRYPTION_README.md: 详细的加密系统说明文档
- 支持自动检测现有密钥并只生成缺失的密钥
- 完善的权限管理和安全验证
- 兼容macOS和Linux的跨平台支持

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(api): 添加加密API端点和Gin框架集成

- 新增CryptoHandler处理加密相关API请求
- 提供/api/crypto/public-key端点获取RSA公钥
- 提供/api/crypto/decrypt端点解密敏感数据
- 适配Gin框架的HTTP处理器格式
- 集成CryptoService到API服务器
- 支持前端加密数据传输和解密

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(web): 添加前端加密服务和两阶段密钥输入组件

- CryptoService: Web Crypto API集成,支持RSA-OAEP加密
- TwoStageKeyModal: 安全的两阶段私钥输入组件,支持剪贴板混淆
- 完善国际化翻译支持加密相关UI文本
- 修复TypeScript类型错误和编译问题
- 支持前端敏感数据加密传输到后端
- 增强用户隐私保护和数据安全

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(auth): 增强JWT认证安全性

- 优先使用环境变量JWT_SECRET而不是数据库配置
- 支持通过.env文件安全配置JWT认证密钥
- 保留数据库配置作为回退机制
- 改进JWT密钥来源日志显示
- 增强系统启动时的安全配置检查
- 支持运行时动态JWT密钥切换

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(docker): 集成加密环境变量到Docker部署

- 添加DATA_ENCRYPTION_KEY环境变量传递到容器
- 添加JWT_SECRET环境变量支持
- 挂载secrets目录使容器可访问RSA密钥文件
- 确保容器内加密服务正常工作
- 解决容器启动失败和加密初始化问题
- 完善Docker Compose加密环境配置

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat(start): 集成自动加密环境检测和设置

- 增强check_encryption()函数检测JWT_SECRET和DATA_ENCRYPTION_KEY
- 自动运行setup_encryption.sh当检测到缺失密钥时
- 改进加密状态显示,包含RSA+AES+JWT全套加密信息
- 优化用户体验,提供清晰的加密配置反馈
- 支持一键设置完整加密环境
- 确保容器启动前加密环境就绪

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: format fix

* fix(security): 修复前端模型和交易所配置敏感数据明文传输

- 在handleSaveModelConfig中对API密钥进行RSA-OAEP加密
- 在handleSaveExchangeConfig中对API密钥、Secret密钥和Aster私钥进行加密
- 只有非空敏感数据才进行加密处理
- 添加加密失败错误处理和用户友好提示
- 增加encryptionFailed翻译键的中英文支持
- 使用用户ID和会话ID作为加密上下文增强安全性

这修复了之前敏感数据在网络传输中以明文形式发送的安全漏洞。

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(crypto): 修复后端加密服务集成和缺失的加密端点

- 添加Server结构体缺少的cryptoService字段
- 实现handleUpdateModelConfigsEncrypted处理器用于模型配置加密传输
- 修复handleUpdateExchangeConfigsEncrypted中的函数调用
- 在前端API中添加updateModelConfigsEncrypted方法
- 统一RSA密钥路径从secrets/rsa_key改为keys/rsa_private.key
- 确保前端可以使用加密端点安全传输敏感数据
- 兼容原有加密通信模式和二段输入私钥功能

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: icy <icyoung520@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Icyoung
2025-11-08 02:03:09 +08:00
committed by GitHub
parent 5c2a2bd77d
commit 079995e458
21 changed files with 2478 additions and 458 deletions

317
scripts/setup_encryption.sh Executable file
View File

@@ -0,0 +1,317 @@
#!/bin/bash
# Mars AI交易系统加密环境设置脚本
# 一键生成RSA密钥对和数据加密密钥完整设置加密环境
set -e # 遇到错误立即退出
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# 获取脚本所在目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
echo -e "${PURPLE}╔════════════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${PURPLE}║ Mars AI交易系统 ║${NC}"
echo -e "${PURPLE}║ 🔐 加密环境一键设置工具 ║${NC}"
echo -e "${PURPLE}║ ║${NC}"
echo -e "${PURPLE}║ 功能: 生成RSA密钥对 + 数据加密密钥 + 配置环境变量 ║${NC}"
echo -e "${PURPLE}╚════════════════════════════════════════════════════════════════════════╝${NC}"
echo
# 检查依赖
echo -e "${CYAN}🔍 检查系统依赖...${NC}"
# 检查 OpenSSL
if ! command -v openssl &> /dev/null; then
echo -e "${RED}❌ 错误: 系统中未安装 OpenSSL${NC}"
echo -e "请安装 OpenSSL:"
echo -e " macOS: ${YELLOW}brew install openssl${NC}"
echo -e " Ubuntu/Debian: ${YELLOW}sudo apt-get install openssl${NC}"
echo -e " CentOS/RHEL: ${YELLOW}sudo yum install openssl${NC}"
exit 1
fi
echo -e "${GREEN}✓ OpenSSL: $(openssl version)${NC}"
# 进入项目根目录
cd "$PROJECT_ROOT"
echo -e "${GREEN}✓ 工作目录: $(pwd)${NC}"
# 配置参数
RSA_KEY_SIZE=2048
SECRETS_DIR="secrets"
PRIVATE_KEY_FILE="$SECRETS_DIR/rsa_key"
PUBLIC_KEY_FILE="$SECRETS_DIR/rsa_key.pub"
echo
echo -e "${BLUE}📋 配置参数:${NC}"
echo -e " • RSA密钥大小: ${YELLOW}$RSA_KEY_SIZE bits${NC}"
echo -e " • 私钥文件: ${YELLOW}$PRIVATE_KEY_FILE${NC}"
echo -e " • 公钥文件: ${YELLOW}$PUBLIC_KEY_FILE${NC}"
echo -e " • AES密钥: ${YELLOW}256 bits (自动生成)${NC}"
# 询问用户确认
echo
read -p "是否继续设置加密环境? [Y/n]: " -n 1 -r
echo
if [[ $REPLY =~ ^[Nn]$ ]]; then
echo -e "${BLUE} 操作已取消${NC}"
exit 0
fi
echo
echo -e "${CYAN}🚀 开始设置加密环境...${NC}"
# ============= 步骤1: 创建目录 =============
echo
echo -e "${YELLOW}📁 步骤 1/4: 创建必要目录...${NC}"
if [ ! -d "$SECRETS_DIR" ]; then
mkdir -p "$SECRETS_DIR"
chmod 700 "$SECRETS_DIR"
echo -e "${GREEN}✓ 创建 $SECRETS_DIR 目录${NC}"
else
echo -e "${GREEN}$SECRETS_DIR 目录已存在${NC}"
fi
if [ ! -d "scripts" ]; then
mkdir -p "scripts"
echo -e "${GREEN}✓ 创建 scripts 目录${NC}"
else
echo -e "${GREEN}✓ scripts 目录已存在${NC}"
fi
# ============= 步骤2: 生成RSA密钥对 =============
echo
echo -e "${YELLOW}🔐 步骤 2/4: 生成 RSA-$RSA_KEY_SIZE 密钥对...${NC}"
# 检查现有RSA密钥
if [ -f "$PRIVATE_KEY_FILE" ] || [ -f "$PUBLIC_KEY_FILE" ]; then
echo -e "${YELLOW}⚠️ 检测到现有的RSA密钥文件${NC}"
read -p "是否重新生成RSA密钥? [y/N]: " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
rm -f "$PRIVATE_KEY_FILE" "$PUBLIC_KEY_FILE"
echo -e "${YELLOW}🗑️ 删除旧密钥${NC}"
else
echo -e "${BLUE} 保持现有RSA密钥${NC}"
RSA_SKIPPED=true
fi
fi
if [ "$RSA_SKIPPED" != "true" ]; then
# 生成私钥
echo -e " ${CYAN}生成RSA私钥...${NC}"
openssl genrsa -out "$PRIVATE_KEY_FILE" $RSA_KEY_SIZE 2>/dev/null
chmod 600 "$PRIVATE_KEY_FILE"
echo -e "${GREEN} ✓ 私钥生成完成${NC}"
# 生成公钥
echo -e " ${CYAN}提取RSA公钥...${NC}"
openssl rsa -in "$PRIVATE_KEY_FILE" -pubout -out "$PUBLIC_KEY_FILE" 2>/dev/null
chmod 644 "$PUBLIC_KEY_FILE"
echo -e "${GREEN} ✓ 公钥生成完成${NC}"
# 验证密钥
echo -e " ${CYAN}验证密钥对...${NC}"
openssl rsa -in "$PRIVATE_KEY_FILE" -check -noout 2>/dev/null
echo -e "${GREEN} ✓ 密钥验证通过${NC}"
fi
# ============= 步骤3: 生成数据加密密钥和JWT密钥 =============
echo
echo -e "${YELLOW}🔑 步骤 3/4: 生成 AES-256 数据加密密钥和JWT认证密钥...${NC}"
# 检查现有密钥
DATA_KEY_EXISTS=false
JWT_KEY_EXISTS=false
if [ -f ".env" ]; then
if grep -q "^DATA_ENCRYPTION_KEY=" .env; then
DATA_KEY_EXISTS=true
fi
if grep -q "^JWT_SECRET=" .env; then
JWT_KEY_EXISTS=true
fi
fi
if [ "$DATA_KEY_EXISTS" = "true" ] || [ "$JWT_KEY_EXISTS" = "true" ]; then
echo -e "${YELLOW}⚠️ 检测到现有的密钥配置${NC}"
if [ "$DATA_KEY_EXISTS" = "true" ]; then
echo -e " • 数据加密密钥已存在"
fi
if [ "$JWT_KEY_EXISTS" = "true" ]; then
echo -e " • JWT认证密钥已存在"
fi
read -p "是否重新生成所有密钥? [y/N]: " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${BLUE} 保持现有密钥${NC}"
KEY_SKIPPED=true
# 读取现有密钥
if [ "$DATA_KEY_EXISTS" = "true" ]; then
DATA_KEY=$(grep "^DATA_ENCRYPTION_KEY=" .env | cut -d'=' -f2)
fi
if [ "$JWT_KEY_EXISTS" = "true" ]; then
JWT_KEY=$(grep "^JWT_SECRET=" .env | cut -d'=' -f2)
fi
fi
fi
if [ "$KEY_SKIPPED" != "true" ]; then
# 生成新的密钥
echo -e " ${CYAN}生成AES-256数据加密密钥...${NC}"
DATA_KEY=$(openssl rand -base64 32)
echo -e "${GREEN} ✓ 数据加密密钥生成完成${NC}"
echo -e " ${CYAN}生成JWT认证密钥...${NC}"
JWT_KEY=$(openssl rand -base64 64)
echo -e "${GREEN} ✓ JWT认证密钥生成完成${NC}"
# 保存到.env文件
if [ -f ".env" ]; then
# 更新现有文件
if grep -q "^DATA_ENCRYPTION_KEY=" .env; then
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' "s/^DATA_ENCRYPTION_KEY=.*/DATA_ENCRYPTION_KEY=$DATA_KEY/" .env
else
sed -i "s/^DATA_ENCRYPTION_KEY=.*/DATA_ENCRYPTION_KEY=$DATA_KEY/" .env
fi
else
echo "DATA_ENCRYPTION_KEY=$DATA_KEY" >> .env
fi
if grep -q "^JWT_SECRET=" .env; then
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i '' "s/^JWT_SECRET=.*/JWT_SECRET=$JWT_KEY/" .env
else
sed -i "s/^JWT_SECRET=.*/JWT_SECRET=$JWT_KEY/" .env
fi
else
echo "JWT_SECRET=$JWT_KEY" >> .env
fi
else
# 创建新文件
echo "DATA_ENCRYPTION_KEY=$DATA_KEY" > .env
echo "JWT_SECRET=$JWT_KEY" >> .env
fi
chmod 600 .env
echo -e "${GREEN} ✓ 密钥已保存到 .env 文件${NC}"
elif [ "$DATA_KEY_EXISTS" != "true" ] || [ "$JWT_KEY_EXISTS" != "true" ]; then
# 生成缺失的密钥
if [ "$DATA_KEY_EXISTS" != "true" ]; then
echo -e " ${CYAN}生成缺失的AES-256数据加密密钥...${NC}"
DATA_KEY=$(openssl rand -base64 32)
echo "DATA_ENCRYPTION_KEY=$DATA_KEY" >> .env
echo -e "${GREEN} ✓ 数据加密密钥生成完成${NC}"
fi
if [ "$JWT_KEY_EXISTS" != "true" ]; then
echo -e " ${CYAN}生成缺失的JWT认证密钥...${NC}"
JWT_KEY=$(openssl rand -base64 64)
echo "JWT_SECRET=$JWT_KEY" >> .env
echo -e "${GREEN} ✓ JWT认证密钥生成完成${NC}"
fi
chmod 600 .env
echo -e "${GREEN} ✓ 密钥已保存到 .env 文件${NC}"
fi
# ============= 步骤4: 验证和总结 =============
echo
echo -e "${YELLOW}✅ 步骤 4/4: 环境验证和总结...${NC}"
# 验证文件存在性和权限
echo -e " ${CYAN}验证文件和权限...${NC}"
if [ -f "$PRIVATE_KEY_FILE" ]; then
PRIVATE_PERM=$(stat -f "%A" "$PRIVATE_KEY_FILE" 2>/dev/null || stat -c "%a" "$PRIVATE_KEY_FILE" 2>/dev/null)
echo -e "${GREEN} ✓ 私钥文件: $PRIVATE_KEY_FILE (权限: $PRIVATE_PERM)${NC}"
else
echo -e "${RED} ❌ 私钥文件不存在${NC}"
exit 1
fi
if [ -f "$PUBLIC_KEY_FILE" ]; then
PUBLIC_PERM=$(stat -f "%A" "$PUBLIC_KEY_FILE" 2>/dev/null || stat -c "%a" "$PUBLIC_KEY_FILE" 2>/dev/null)
echo -e "${GREEN} ✓ 公钥文件: $PUBLIC_KEY_FILE (权限: $PUBLIC_PERM)${NC}"
else
echo -e "${RED} ❌ 公钥文件不存在${NC}"
exit 1
fi
if [ -f ".env" ] && grep -q "^DATA_ENCRYPTION_KEY=" .env && grep -q "^JWT_SECRET=" .env; then
ENV_PERM=$(stat -f "%A" ".env" 2>/dev/null || stat -c "%a" ".env" 2>/dev/null)
echo -e "${GREEN} ✓ 环境文件: .env (权限: $ENV_PERM)${NC}"
echo -e "${GREEN} 包含: DATA_ENCRYPTION_KEY, JWT_SECRET${NC}"
else
echo -e "${RED} ❌ 环境文件不存在或缺少必要密钥${NC}"
exit 1
fi
# 测试密钥功能
echo -e " ${CYAN}测试密钥功能...${NC}"
TEST_DATA="Hello Mars AI Trading System"
ENCRYPTED=$(echo "$TEST_DATA" | openssl rsautl -encrypt -pubin -inkey "$PUBLIC_KEY_FILE" | base64)
DECRYPTED=$(echo "$ENCRYPTED" | base64 -d | openssl rsautl -decrypt -inkey "$PRIVATE_KEY_FILE")
if [ "$DECRYPTED" = "$TEST_DATA" ]; then
echo -e "${GREEN} ✓ RSA加密/解密测试通过${NC}"
else
echo -e "${RED} ❌ RSA加密/解密测试失败${NC}"
exit 1
fi
# 显示最终结果
echo
echo -e "${GREEN}🎉 加密环境设置完成!${NC}"
echo
echo -e "${PURPLE}╔════════════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${PURPLE}║ 设置完成摘要 ║${NC}"
echo -e "${PURPLE}╠════════════════════════════════════════════════════════════════════════╣${NC}"
echo -e "${PURPLE}${NC} ${BLUE}RSA密钥对:${NC} ${PURPLE}${NC}"
echo -e "${PURPLE}${NC} 私钥: ${YELLOW}$PRIVATE_KEY_FILE${NC} ${PURPLE}${NC}"
echo -e "${PURPLE}${NC} 公钥: ${YELLOW}$PUBLIC_KEY_FILE${NC} ${PURPLE}${NC}"
echo -e "${PURPLE}${NC} 大小: ${YELLOW}$RSA_KEY_SIZE bits${NC} ${PURPLE}${NC}"
echo -e "${PURPLE}${NC} ${PURPLE}${NC}"
echo -e "${PURPLE}${NC} ${BLUE}安全密钥配置:${NC} ${PURPLE}${NC}"
echo -e "${PURPLE}${NC} 文件: ${YELLOW}.env${NC} ${PURPLE}${NC}"
echo -e "${PURPLE}${NC} 数据加密: ${YELLOW}DATA_ENCRYPTION_KEY (AES-256-GCM)${NC} ${PURPLE}${NC}"
echo -e "${PURPLE}${NC} JWT认证: ${YELLOW}JWT_SECRET (HS256)${NC} ${PURPLE}${NC}"
echo -e "${PURPLE}╚════════════════════════════════════════════════════════════════════════╝${NC}"
# 使用指南
echo
echo -e "${BLUE}📋 使用指南:${NC}"
echo
echo -e "${YELLOW}1. 启动Mars AI交易系统:${NC}"
echo -e " source .env && ./mars"
echo
echo -e "${YELLOW}2. Docker部署:${NC}"
echo -e " docker run --env-file .env mars-ai-trading"
echo
echo -e "${YELLOW}3. 查看公钥内容:${NC}"
echo -e " cat $PUBLIC_KEY_FILE"
echo
echo -e "${YELLOW}4. 测试加密API:${NC}"
echo -e " curl http://localhost:8080/api/crypto/public-key"
# 安全提醒
echo
echo -e "${RED}🔒 安全提醒:${NC}"
echo -e " • 私钥文件 ($PRIVATE_KEY_FILE) 权限已设置为 600"
echo -e " • 环境文件 (.env) 权限已设置为 600"
echo -e " • 请勿将私钥和数据密钥提交到版本控制系统"
echo -e " • 建议在生产环境中使用密钥管理服务"
echo -e " • 定期备份密钥文件"
echo
echo -e "${GREEN}✅ Mars AI交易系统加密环境设置完成${NC}"