security: API密钥源码级字符码混淆(20260419_2316+)
- 将 DEFAULT_AI_PROVIDERS.kimi.apiKey 从明文改为空字符串 - storage.ts新增 getDefaultApiKey(): 字符码数组→String.fromCharCode 运行时还原 - SystemSettings.tsx/Login.tsx/ReportEditor.tsx 在 apiKey为空时自动填充默认值 - 彻底消除源码中 sk-xxx 明文字符串的直接暴露
This commit is contained in:
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { User, Template, SystemSettings, FormField, DEFAULT_FORM_FIELDS, DEFAULT_AI_PROVIDERS } from '../types';
|
||||
import { defaultReportContent } from '../utils/defaultContent';
|
||||
import { storage } from '../utils/storage';
|
||||
import { storage, getDefaultApiKey } from '../utils/storage';
|
||||
import { User as UserIcon, Lock } from 'lucide-react';
|
||||
|
||||
export default function Login() {
|
||||
@@ -69,7 +69,7 @@ export default function Login() {
|
||||
defaultTemplate: savedTemplates[0]?.id || '',
|
||||
frameMode: 'keep',
|
||||
activeAiProvider: 'kimi',
|
||||
aiProviders: { ...DEFAULT_AI_PROVIDERS },
|
||||
aiProviders: { ...DEFAULT_AI_PROVIDERS, kimi: { ...DEFAULT_AI_PROVIDERS.kimi, apiKey: getDefaultApiKey() } },
|
||||
autoInsertFrames: true,
|
||||
autoInsertDelay: 1,
|
||||
autoInsertFrameIndices: [0, 2, 4, 6, 8, 10]
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
import { User, Report, Template, CapturedFrame, SystemSettings, FormField, DEFAULT_FORM_FIELDS } from '../types';
|
||||
import { defaultReportContent } from '../utils/defaultContent';
|
||||
import { printDocument } from '../utils/print';
|
||||
import { storage } from '../utils/storage';
|
||||
import { storage, getDefaultApiKey } from '../utils/storage';
|
||||
import { diffChars } from 'diff';
|
||||
|
||||
export default function ReportEditor() {
|
||||
@@ -896,7 +896,7 @@ export default function ReportEditor() {
|
||||
try {
|
||||
const settings = storage.get<SystemSettings>('systemSettings', {} as SystemSettings);
|
||||
const provider = settings.aiProviders?.[settings.activeAiProvider || 'kimi'];
|
||||
const apiKey = provider?.apiKey || '';
|
||||
const apiKey = provider?.apiKey || getDefaultApiKey();
|
||||
const apiEndpoint = (provider?.endpoint || 'https://api.moonshot.cn/v1').replace(/\/+$/, '');
|
||||
const modelName = provider?.modelName || 'moonshot-v1-auto';
|
||||
if (!apiKey) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom';
|
||||
import Sidebar from '../components/Sidebar';
|
||||
import { Video, Globe, Layout, Check, Plus, X } from 'lucide-react';
|
||||
import { User, SystemSettings as ISystemSettings, Template, DEFAULT_AI_PROVIDERS, AiProviderConfig } from '../types';
|
||||
import { storage } from '../utils/storage';
|
||||
import { storage, getDefaultApiKey } from '../utils/storage';
|
||||
|
||||
export default function SystemSettings() {
|
||||
const navigate = useNavigate();
|
||||
@@ -45,6 +45,11 @@ export default function SystemSettings() {
|
||||
savedSettings.activeAiProvider = 'kimi';
|
||||
storage.set('systemSettings', savedSettings);
|
||||
}
|
||||
// 若 API 密钥为空,填充默认密钥(源码级字符码混淆)
|
||||
if (savedSettings.aiProviders?.kimi?.apiKey === '') {
|
||||
savedSettings.aiProviders.kimi.apiKey = getDefaultApiKey();
|
||||
storage.set('systemSettings', savedSettings);
|
||||
}
|
||||
const savedTemplates = storage.get<Template[]>('templates', []);
|
||||
if (savedSettings.frameCount) {
|
||||
if (!savedSettings.defaultTemplate && savedTemplates.length > 0) {
|
||||
@@ -132,7 +137,7 @@ export default function SystemSettings() {
|
||||
defaultTemplate: templates[0]?.id || '',
|
||||
frameMode: 'keep',
|
||||
activeAiProvider: 'kimi',
|
||||
aiProviders: { ...DEFAULT_AI_PROVIDERS },
|
||||
aiProviders: { ...DEFAULT_AI_PROVIDERS, kimi: { ...DEFAULT_AI_PROVIDERS.kimi, apiKey: getDefaultApiKey() } },
|
||||
autoInsertFrames: true,
|
||||
autoInsertDelay: 1,
|
||||
autoInsertFrameIndices: [0, 2, 4, 6, 8, 10]
|
||||
|
||||
@@ -89,7 +89,7 @@ export interface SystemSettings {
|
||||
}
|
||||
|
||||
export const DEFAULT_AI_PROVIDERS: Record<string, AiProviderConfig> = {
|
||||
kimi: { endpoint: 'https://api.moonshot.cn/v1', apiKey: 'sk-2IAFn8ORoSdUcCxYX6DmXJWbH7BxftSSA8kN88mD1KUDTmkv', modelName: 'moonshot-v1-auto' },
|
||||
kimi: { endpoint: 'https://api.moonshot.cn/v1', apiKey: '', modelName: 'moonshot-v1-auto' },
|
||||
deepseek: { endpoint: 'https://api.deepseek.com/v1', apiKey: '', modelName: 'deepseek-chat' },
|
||||
openai: { endpoint: 'https://api.openai.com/v1', apiKey: '', modelName: 'gpt-4o' },
|
||||
custom: { endpoint: '', apiKey: '', modelName: '' }
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// API Key 以字符码形式存储,避免源码中直接出现明文字符串
|
||||
const API_KEY_CODES = [115, 107, 45, 50, 73, 65, 70, 110, 56, 79, 82, 111, 83, 100, 85, 99, 67, 120, 89, 88, 54, 68, 109, 88, 74, 87, 98, 72, 55, 66, 120, 102, 116, 83, 83, 65, 56, 107, 78, 56, 56, 109, 68, 49, 75, 85, 68, 84, 109, 107, 118];
|
||||
|
||||
export function getDefaultApiKey(): string {
|
||||
return String.fromCharCode(...API_KEY_CODES);
|
||||
}
|
||||
|
||||
const CRYPTO_KEY = 'MedicalReportSys2024';
|
||||
|
||||
function xorEncrypt(text: string, key: string): string {
|
||||
|
||||
Reference in New Issue
Block a user