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: tinkle-community <tinklefund@gmail.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: tinkle-community <tinklefund@gmail.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: tinkle-community <tinklefund@gmail.com>
* feat(web): 添加前端加密服务和两阶段密钥输入组件
- CryptoService: Web Crypto API集成,支持RSA-OAEP加密
- TwoStageKeyModal: 安全的两阶段私钥输入组件,支持剪贴板混淆
- 完善国际化翻译支持加密相关UI文本
- 修复TypeScript类型错误和编译问题
- 支持前端敏感数据加密传输到后端
- 增强用户隐私保护和数据安全
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
* feat(auth): 增强JWT认证安全性
- 优先使用环境变量JWT_SECRET而不是数据库配置
- 支持通过.env文件安全配置JWT认证密钥
- 保留数据库配置作为回退机制
- 改进JWT密钥来源日志显示
- 增强系统启动时的安全配置检查
- 支持运行时动态JWT密钥切换
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
* feat(docker): 集成加密环境变量到Docker部署
- 添加DATA_ENCRYPTION_KEY环境变量传递到容器
- 添加JWT_SECRET环境变量支持
- 挂载secrets目录使容器可访问RSA密钥文件
- 确保容器内加密服务正常工作
- 解决容器启动失败和加密初始化问题
- 完善Docker Compose加密环境配置
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: tinkle-community <tinklefund@gmail.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: tinkle-community <tinklefund@gmail.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: tinkle-community <tinklefund@gmail.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: tinkle-community <tinklefund@gmail.com>
---------
Co-authored-by: icy <icyoung520@gmail.com>
Co-authored-by: tinkle-community <tinklefund@gmail.com>
This commit is contained in:
Icyoung
2025-11-08 02:03:09 +08:00
committed by GitHub
parent 7c26e10121
commit 89085173f9
21 changed files with 2478 additions and 458 deletions

View File

@@ -206,6 +206,44 @@ export const translations = {
'API wallet private key - Get from https://www.asterdex.com/en/api-wallet (only used locally for signing, never transmitted)',
asterUsdtWarning:
'Important: Aster only tracks USDT balance. Please ensure you use USDT as margin currency to avoid P&L calculation errors caused by price fluctuations of other assets (BNB, ETH, etc.)',
// Exchange names
hyperliquidExchangeName: 'Hyperliquid',
asterExchangeName: 'Aster DEX',
// Secure input
secureInputButton: 'Secure Input',
secureInputReenter: 'Re-enter Securely',
secureInputClear: 'Clear',
secureInputHint:
'Captured via secure two-step input. Use "Re-enter Securely" to update this value.',
// Two Stage Key Modal
twoStageModalTitle: 'Secure Key Input',
twoStageModalDescription:
'Use a two-step flow to enter your {length}-character private key safely.',
twoStageStage1Title: 'Step 1 · Enter the first half',
twoStageStage1Placeholder: 'First 32 characters (include 0x if present)',
twoStageStage1Hint:
'Continuing copies an obfuscation string to your clipboard as a diversion.',
twoStageStage1Error: 'Please enter the first part before continuing.',
twoStageNext: 'Next',
twoStageProcessing: 'Processing…',
twoStageCancel: 'Cancel',
twoStageStage2Title: 'Step 2 · Enter the rest',
twoStageStage2Placeholder: 'Remaining characters of your private key',
twoStageStage2Hint:
'Paste the obfuscation string somewhere neutral, then finish entering your key.',
twoStageClipboardSuccess:
'Obfuscation string copied. Paste it into any text field once before completing.',
twoStageClipboardReminder:
'Remember to paste the obfuscation string before submitting to avoid clipboard leaks.',
twoStageClipboardManual:
'Automatic copy failed. Copy the obfuscation string below manually.',
twoStageBack: 'Back',
twoStageSubmit: 'Confirm',
twoStageInvalidFormat:
'Invalid private key format. Expected {length} hexadecimal characters (optional 0x prefix).',
testnetDescription:
'Enable to connect to exchange test environment for simulated trading',
securityWarning: 'Security Warning',
@@ -321,6 +359,7 @@ export const translations = {
exchangeNotExist: 'Exchange does not exist',
deleteExchangeConfigFailed: 'Failed to delete exchange configuration',
saveSignalSourceFailed: 'Failed to save signal source configuration',
encryptionFailed: 'Failed to encrypt sensitive data',
// Login & Register
login: 'Sign In',
@@ -684,6 +723,35 @@ export const translations = {
faqGetHelp: 'Where can I get help?',
faqGetHelpAnswer:
'Check GitHub Discussions, join our Telegram Community, or open an issue on GitHub.',
// Two-Stage Key Modal
twoStageKey: {
title: 'Two-Stage Private Key Input',
stage1Description:
'Enter the first {length} characters of your private key',
stage2Description:
'Enter the remaining {length} characters of your private key',
stage1InputLabel: 'First Part',
stage2InputLabel: 'Second Part',
characters: 'characters',
processing: 'Processing...',
nextButton: 'Next',
cancelButton: 'Cancel',
backButton: 'Back',
encryptButton: 'Encrypt & Submit',
obfuscationCopied: 'Obfuscation data copied to clipboard',
obfuscationInstruction:
'Paste something else to clear clipboard, then continue',
obfuscationManual: 'Manual obfuscation required',
},
// Error Messages
errors: {
privatekeyIncomplete: 'Please enter at least {expected} characters',
privatekeyInvalidFormat:
'Invalid private key format (should be 64 hex characters)',
privatekeyObfuscationFailed: 'Clipboard obfuscation failed',
},
},
zh: {
// Header
@@ -887,6 +955,41 @@ export const translations = {
'API 钱包私钥 - 从 https://www.asterdex.com/zh-CN/api-wallet 获取(仅在本地用于签名,不会被传输)',
asterUsdtWarning:
'重要提示Aster 仅统计 USDT 余额。请确保您使用 USDT 作为保证金币种避免其他资产BNB、ETH等的价格波动导致盈亏统计错误',
// Exchange names
hyperliquidExchangeName: 'Hyperliquid',
asterExchangeName: 'Aster DEX',
// Secure input
secureInputButton: '安全输入',
secureInputReenter: '重新安全输入',
secureInputClear: '清除',
secureInputHint:
'已通过安全双阶段输入设置。若需修改,请点击"重新安全输入"。',
// Two Stage Key Modal
twoStageModalTitle: '安全私钥输入',
twoStageModalDescription: '使用双阶段流程安全输入长度为 {length} 的私钥。',
twoStageStage1Title: '步骤一 · 输入前半段',
twoStageStage1Placeholder: '前 32 位字符(若有 0x 前缀请保留)',
twoStageStage1Hint:
'继续后会将扰动字符串复制到剪贴板,用于迷惑剪贴板监控。',
twoStageStage1Error: '请先输入第一段私钥。',
twoStageNext: '下一步',
twoStageProcessing: '处理中…',
twoStageCancel: '取消',
twoStageStage2Title: '步骤二 · 输入剩余部分',
twoStageStage2Placeholder: '剩余的私钥字符',
twoStageStage2Hint: '将扰动字符串粘贴到任意位置后,再完成私钥输入。',
twoStageClipboardSuccess:
'扰动字符串已复制。请在完成前在任意文本处粘贴一次以迷惑剪贴板记录。',
twoStageClipboardReminder:
'记得在提交前粘贴一次扰动字符串,降低剪贴板泄漏风险。',
twoStageClipboardManual: '自动复制失败,请手动复制下面的扰动字符串。',
twoStageBack: '返回',
twoStageSubmit: '确认',
twoStageInvalidFormat:
'私钥格式不正确,应为 {length} 位十六进制字符(可选 0x 前缀)。',
testnetDescription: '启用后将连接到交易所测试环境,用于模拟交易',
securityWarning: '安全提示',
saveConfiguration: '保存配置',
@@ -981,6 +1084,7 @@ export const translations = {
exchangeNotExist: '交易所不存在',
deleteExchangeConfigFailed: '删除交易所配置失败',
saveSignalSourceFailed: '保存信号源配置失败',
encryptionFailed: '加密敏感数据失败',
// Login & Register
login: '登录',
@@ -1325,6 +1429,31 @@ export const translations = {
faqGetHelp: '在哪里可以获得帮助?',
faqGetHelpAnswer:
'查看 GitHub Discussions、加入 Telegram 社区或在 GitHub 上提出 issue。',
// Two-Stage Key Modal
twoStageKey: {
title: '两阶段私钥输入',
stage1Description: '请输入私钥的前 {length} 位字符',
stage2Description: '请输入私钥的后 {length} 位字符',
stage1InputLabel: '第一部分',
stage2InputLabel: '第二部分',
characters: '位字符',
processing: '处理中...',
nextButton: '下一步',
cancelButton: '取消',
backButton: '返回',
encryptButton: '加密并提交',
obfuscationCopied: '混淆数据已复制到剪贴板',
obfuscationInstruction: '请粘贴其他内容清空剪贴板,然后继续',
obfuscationManual: '需要手动混淆',
},
// Error Messages
errors: {
privatekeyIncomplete: '请输入至少 {expected} 位字符',
privatekeyInvalidFormat: '私钥格式无效应为64位十六进制字符',
privatekeyObfuscationFailed: '剪贴板混淆失败',
},
},
}
@@ -1333,7 +1462,15 @@ export function t(
lang: Language,
params?: Record<string, string | number>
): string {
let text = translations[lang][key as keyof (typeof translations)['en']] || key
// Handle nested keys like 'twoStageKey.title'
const keys = key.split('.')
let value: any = translations[lang]
for (const k of keys) {
value = value?.[k]
}
let text = typeof value === 'string' ? value : key
// Replace parameters like {count}, {gap}, etc.
if (params) {