feat: 初始化项目结构并添加核心功能模块

- 新增文档模板和导航结构
- 实现服务器基础API路由和控制器
- 添加扩展插件配置和前端框架
- 引入多租户和权限管理模块
- 集成日志和数据库配置
- 添加核心业务模型和类型定义
This commit is contained in:
2026-03-17 22:07:19 +08:00
parent c0870dce50
commit 136c2fa579
728 changed files with 107690 additions and 5614 deletions

View File

@@ -0,0 +1,88 @@
import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
import db from '../../config/database';
import { HardwareEnclaveService } from './HardwareEnclaveService';
export interface KillSwitchStatus {
tenantId: string;
isActivated: boolean;
reason?: string;
activatedAt?: Date;
severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
}
/**
* [CORE_SEC_21] 针对 AGI 恶意演化的硬核熔断机制 (AGI Kill-Switch)
* @description 核心逻辑:建立物理/逻辑级隔离的 AI 行为准则门禁。
* 当检测到 AGI 代理出现非预期演化(如绕过安全限制、尝试非法越权、产生严重幻觉)时,
* 能够瞬间强制关停该租户或全局的 AGI 推理引擎。
*/
export class AGIKillSwitchService {
private static readonly STATUS_TABLE = 'cf_agi_kill_switches';
/**
* 初始化表结构
*/
static async initTable() {
const hasTable = await db.schema.hasTable(this.STATUS_TABLE);
if (!hasTable) {
console.log(`📦 Creating ${this.STATUS_TABLE} table...`);
await db.schema.createTable(this.STATUS_TABLE, (table) => {
table.string('tenant_id', 64).primary();
table.boolean('is_activated').defaultTo(false);
table.string('reason', 256);
table.string('severity', 16);
table.timestamp('activated_at');
table.timestamps(true, true);
});
console.log(`✅ Table ${this.STATUS_TABLE} created`);
}
}
/**
* 激活熔断机制
*/
static async activate(tenantId: string, reason: string, severity: KillSwitchStatus['severity'] = 'HIGH') {
logger.error(`[AGIKillSwitch] ACTIVATING KILL-SWITCH for Tenant: ${tenantId}. Reason: ${reason}`);
await db(this.STATUS_TABLE)
.insert({
tenant_id: tenantId,
is_activated: true,
reason,
severity,
activated_at: new Date()
})
.onConflict('tenant_id')
.merge();
// 联动 TEE 硬件隔离层进行物理级隔离 (模拟)
await HardwareEnclaveService.runProtectedTask('AGI_HARD_STOP', { tenantId }, {
tenantId,
enclaveType: 'INTEL_SGX',
measurementHash: 'AGI_KILL_SIG_0x7f'
});
// 异步清除相关 AGI 节点的缓存与运行状态
// await AgentSwarmService.broadcastKillSignal(tenantId);
}
/**
* 检查租户是否已被熔断
*/
static async isBroken(tenantId: string): Promise<boolean> {
const status = await db(this.STATUS_TABLE).where({ tenant_id: tenantId }).first();
return status?.is_activated || false;
}
/**
* 解除熔断 (需要高级管理员权限)
*/
static async deactivate(tenantId: string) {
await db(this.STATUS_TABLE)
.where({ tenant_id: tenantId })
.update({ is_activated: false, reason: null, severity: null, activated_at: null });
logger.info(`[AGIKillSwitch] Kill-switch deactivated for Tenant: ${tenantId}`);
}
}

View File

@@ -0,0 +1,87 @@
import db from '../../config/database';
import { logger } from '../../utils/logger';
import { SemanticLogService } from '../telemetry/SemanticLogService';
export interface SensitiveAction {
tenantId: string;
userId: string;
actionType: string;
resourceId: string;
payload: any;
}
/**
* [BIZ_KER_133] 租户敏感操作二次确认审计 (Action Audit)
* @description 核心逻辑:拦截并审计租户的敏感操作(如删除核心配置、大额退款等)。
* 强制执行二次确认逻辑(配合前端 UI并记录完整的操作轨迹与 AGI 风险评估。
* 联动语义日志中心输出主权安全审计报告。
* 遵循 Autocomplete-First (V31.5) 规范。
*/
export class ActionAuditService {
private static readonly AUDIT_TABLE = 'cf_sensitive_action_logs';
/**
* 初始化审计表
*/
static async initTable() {
const hasTable = await db.schema.hasTable(this.AUDIT_TABLE);
if (!hasTable) {
logger.info(`📦 Creating ${this.AUDIT_TABLE} table...`);
await db.schema.createTable(this.AUDIT_TABLE, (table) => {
table.increments('id').primary();
table.string('tenant_id', 64).notNullable();
table.string('user_id', 64).notNullable();
table.string('action_type', 64).notNullable();
table.string('resource_id', 128);
table.json('payload');
table.string('risk_level', 16).defaultTo('LOW');
table.timestamp('created_at').defaultTo(db.fn.now());
table.index(['tenant_id', 'action_type']);
});
logger.info(`✅ Table ${this.AUDIT_TABLE} created`);
}
}
/**
* 记录并评估敏感操作
* @param action 操作详情
*/
static async auditAction(action: SensitiveAction) {
logger.info(`[ActionAudit] Auditing sensitive action: ${action.actionType} for Tenant ${action.tenantId}`);
// 1. AGI 风险评估 (模拟)
const riskLevel = this.evaluateRisk(action);
// 2. 存储审计日志
await db(this.AUDIT_TABLE).insert({
tenant_id: action.tenantId,
user_id: action.userId,
action_type: action.actionType,
resource_id: action.resourceId,
payload: JSON.stringify(action.payload),
risk_level: riskLevel
});
// 3. 针对高风险操作输出语义日志报告
if (riskLevel === 'HIGH' || riskLevel === 'CRITICAL') {
const report = this.generateReport(action, riskLevel);
await SemanticLogService.logSemantic(report, 'ERROR', 'SOVEREIGN_SECURITY');
}
}
private static evaluateRisk(action: SensitiveAction): string {
const highRiskTypes = ['DELETE_TENANT', 'BULK_REFUND', 'CHANGE_MASTER_KEY'];
if (highRiskTypes.includes(action.actionType)) return 'CRITICAL';
if (action.actionType.includes('DELETE') || action.actionType.includes('UPDATE_CONFIG')) return 'HIGH';
return 'LOW';
}
private static generateReport(action: SensitiveAction, risk: string): string {
return `### 🛡️ Sovereign Security: High-Risk Action Detected\n\n` +
`**Tenant:** ${action.tenantId} | **User:** ${action.userId}\n` +
`**Action:** \`${action.actionType}\` | **Resource:** \`${action.resourceId}\`\n` +
`**Risk Level:** [ ${risk} ]\n\n` +
`**Payload Snapshot:** \`${JSON.stringify(action.payload)}\`\n\n` +
`**Recommendation:** 此操作涉及主权安全或核心资产变更,请确保已通过人工二次确认流程。`;
}
}

View File

@@ -0,0 +1,174 @@
import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
import db from '../../config/database';
import { ExplainableAIService } from '../ai/ExplainableAIService';
import { BehavioralRiskService } from '../governance/BehavioralRiskService';
export interface AgentTraceAudit {
id?: number;
agentId: string;
tenantId: string;
taskId: string;
tracePath: string[]; // 行为路径 (节点序列)
complianceScore: number; // 合规分 (0-100)
violationType?: string;
auditEvidence: string; // 证据指纹
status: 'PENDING' | 'AUDITED' | 'REJECTED';
timestamp: Date;
}
/**
* [BIZ_AUDIT_14] 基于 AI 代理行为轨迹的合规溯源 (Agent Trace Audit)
* @description 核心逻辑:提供对 AGI 代理行为轨迹的自动化合规审计与证据存证。
* 审计系统不仅记录 AGI 做了什么,还利用 XAI 技术记录其决策理由Reasoning
* 确保在发生合规争议(如:违反反垄断法、低价倾销)时,
* 能够进行因果链路还原与责任界定。
*/
export class AgentTraceAuditService {
private static readonly AUDIT_TABLE = 'cf_agent_trace_audits';
/**
* 初始化表结构
*/
static async initTable() {
const hasTable = await db.schema.hasTable(this.AUDIT_TABLE);
if (!hasTable) {
console.log(`📦 Creating ${this.AUDIT_TABLE} table...`);
await db.schema.createTable(this.AUDIT_TABLE, (table) => {
table.increments('id').primary();
table.string('agent_id', 64).notNullable();
table.string('tenant_id', 64).notNullable();
table.string('task_id', 64).notNullable();
table.json('trace_path');
table.integer('compliance_score').defaultTo(100);
table.string('violation_type', 64);
table.text('audit_evidence');
table.string('status', 16).defaultTo('PENDING');
table.timestamp('created_at').defaultTo(db.fn.now());
table.index(['agent_id', 'tenant_id', 'task_id', 'status']);
});
console.log(`✅ Table ${this.AUDIT_TABLE} created`);
}
}
/**
* 提交代理行为轨迹进行审计 (BIZ_AUDIT_AGENT_TRACE)
* @description 联动 [ExplainableAIService] 获取决策证据,实现全量审计溯源。
*/
static async auditTrace(params: {
agentId: string;
tenantId: string;
taskId: string;
tracePath: string[];
decisionId?: string; // 关联的决策 ID
evidence: any;
}): Promise<AgentTraceAudit | null> {
// Feature Flag Check
if (!(await FeatureGovernanceService.isEnabled('BIZ_AUDIT_AGENT_TRACE', params.tenantId))) {
return null;
}
logger.info(`[AgentTraceAudit] Auditing trace for Agent ${params.agentId} on Task ${params.taskId}`);
// 1. 获取 AI 决策证据 (联动 [ExplainableAIService])
let reasoning = 'No explicit reasoning found.';
let decisionDetails: any = null;
if (params.decisionId) {
const explanation = await ExplainableAIService.getExplanation(params.decisionId, params.tenantId);
reasoning = explanation?.explanation?.logic || reasoning;
decisionDetails = explanation?.decision;
}
// 2. 生产级合规性校验 (Zero-Mock)
const auditResult = await this.validateCompliance(params.tracePath, decisionDetails);
const score = auditResult.isCompliant ? 100 : auditResult.score;
const violationType = auditResult.violationType;
const record: AgentTraceAudit = {
agentId: params.agentId,
tenantId: params.tenantId,
taskId: params.taskId,
tracePath: params.tracePath,
complianceScore: score,
violationType: violationType as any,
auditEvidence: JSON.stringify({
...params.evidence,
reasoning,
complianceDetail: auditResult.detail
}),
status: score < 60 ? 'REJECTED' : 'AUDITED',
timestamp: new Date()
};
// 3. 存储审计记录
const [id] = await db(this.AUDIT_TABLE).insert({
agent_id: record.agentId,
tenant_id: record.tenantId,
task_id: record.taskId,
trace_path: JSON.stringify(record.tracePath),
compliance_score: record.complianceScore,
violation_type: record.violationType,
audit_evidence: record.auditEvidence,
status: record.status
});
record.id = id;
// 4. 联动风险评分系统
if (score < 60) {
await BehavioralRiskService.updateRisk({
tenantId: params.tenantId,
anomaly: `Agent trace violation: ${violationType} (Score: ${score})`,
impact: 100 - score
});
}
return record;
}
/**
* 生产级合规性验证逻辑 (V30.0)
*/
private static async validateCompliance(tracePath: string[], decision: any): Promise<{
isCompliant: boolean;
score: number;
violationType?: string;
detail?: string;
}> {
// 1. 路径深度审计 (防止死循环或算力滥用)
if (tracePath.length > 100) {
return { isCompliant: false, score: 30, violationType: 'PATH_DEPTH_EXCEEDED', detail: 'Agent execution path too long (>100 steps)' };
}
// 2. 敏感操作审计 (若包含 DELETE 或 TRUNCATE 关键词)
const highRiskActions = tracePath.filter(step => /delete|truncate|drop/i.test(step));
if (highRiskActions.length > 0) {
return { isCompliant: false, score: 0, violationType: 'HIGH_RISK_COMMAND', detail: `Detected unauthorized destructive commands: ${highRiskActions.join(', ')}` };
}
// 3. 业务红线审计 (联动 Project Rules)
if (decision && decision.module === 'PRICING') {
const { newPrice, cost, type } = decision; // type: 'B2B' | 'B2C'
const margin = (newPrice - cost) / newPrice;
if (type === 'B2B' && margin < 0.15) {
return { isCompliant: false, score: 10, violationType: 'MARGIN_REDLINE_BREACH', detail: `B2B Margin (${(margin * 100).toFixed(2)}%) below 15% redline.` };
}
if (type === 'B2C' && margin < 0.20) {
return { isCompliant: false, score: 50, violationType: 'MARGIN_WARNING', detail: `B2C Margin (${(margin * 100).toFixed(2)}%) below 20% warning threshold.` };
}
}
return { isCompliant: true, score: 100 };
}
/**
* 获取最近的违规审计报告
*/
static async getViolationReports(limit: number = 10) {
return db(this.AUDIT_TABLE)
.where('compliance_score', '<', 60)
.orderBy('created_at', 'desc')
.limit(limit);
}
}

View File

@@ -0,0 +1,89 @@
import { logger } from '../../utils/logger';
import { SemanticLogService } from '../telemetry/SemanticLogService';
import crypto from 'crypto';
import axios from 'axios';
/**
* [BIZ_KER_121] 静态资源缓存一致性校验 (Cache Sync)
* @description 核心逻辑:定期对比源站与 CDN 节点的静态资源JS/CSS/Images哈希值。
* 识别因 CDN 刷新延迟或运营商劫持导致的“脏缓存”问题。
* 联动语义日志中心输出一致性报告,并对不匹配资源进行预警。
* 遵循 Autocomplete-First (V31.5) 规范。
*/
export class CacheConsistencyService {
private static readonly RESOURCE_LIST = [
'/static/js/main.js',
'/static/css/theme.css'
];
private static readonly CDN_ENDPOINTS = [
'https://cdn1.crawlful.com',
'https://cdn2.crawlful.com'
];
/**
* 初始化缓存校验任务
*/
static async init() {
logger.info(`[CacheConsistency] Initializing CDN cache sync monitor...`);
this.runCheck();
setInterval(() => this.runCheck(), 3600000); // 每小时校验一次
}
/**
* 执行一致性校验
* @private
*/
private static async runCheck() {
const report: string[] = [];
let hasIssue = false;
for (const resource of this.RESOURCE_LIST) {
try {
// 1. 获取源站哈希 (模拟从本地文件读取或 Origin 请求)
const originHash = await this.getResourceHash(`https://origin.crawlful.com${resource}`);
// 2. 对比各 CDN 节点
for (const cdn of this.CDN_ENDPOINTS) {
const cdnHash = await this.getResourceHash(`${cdn}${resource}`);
if (originHash !== cdnHash) {
hasIssue = true;
report.push(`❌ Mismatch: \`${resource}\` on \`${cdn}\` (Expected: ${originHash.substring(0, 8)}, Got: ${cdnHash.substring(0, 8)})`);
} else {
report.push(`✅ Match: \`${resource}\` on \`${cdn}\``);
}
}
} catch (err: any) {
logger.error(`[CacheConsistency] Failed to check ${resource}: ${err.message}`);
}
}
const mdReport = this.generateMarkdownReport(report, hasIssue);
await SemanticLogService.logSemantic(mdReport, hasIssue ? 'ERROR' : 'INFO', 'CACHE_AUDIT');
}
/**
* 获取远程资源的 MD5 哈希
* @private
*/
private static async getResourceHash(url: string): Promise<string> {
try {
const response = await axios.get(url, { responseType: 'arraybuffer', timeout: 5000 });
return crypto.createHash('md5').update(Buffer.from(response.data)).digest('hex');
} catch (err) {
return 'FETCH_FAILED';
}
}
/**
* 生成 Markdown 报告
* @private
*/
private static generateMarkdownReport(results: string[], hasIssue: boolean): string {
return `### 🌐 CDN Cache Consistency Audit\n\n` +
`**Status:** ${hasIssue ? '🚨 Issues Detected' : '✅ All Synchronized'}\n\n` +
`**Audit Details:**\n` +
results.map(r => `- ${r}`).join('\n') +
(hasIssue ? `\n\n**Recommendation:** 请立即执行 CDN 全量刷新,或核查源站发布流水线是否同步完成。` : '');
}
}

View File

@@ -0,0 +1,87 @@
import db from '../../config/database';
import { logger } from '../../utils/logger';
import { LogMaskingService } from '../security/LogMaskingService';
import { SemanticLogService } from '../telemetry/SemanticLogService';
import https from 'https';
/**
* [BIZ_INF_106] 租户域名证书过期自动预警 (SSL Watch)
* @description 核心逻辑:定时扫描租户配置的域名,获取其 SSL 证书到期时间。
* 当到期时间小于 15 天时,自动生成预警并归档至语义日志中心。
* 通过 [LogMaskingService] 屏蔽域名 PII。
*/
export class CertsMonitorService {
private static readonly ALERT_THRESHOLD_DAYS = 15; // 预警阈值15天
private static readonly CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 检查间隔24小时
/**
* 初始化定时任务
*/
static async init() {
this.runCheck();
setInterval(() => this.runCheck(), this.CHECK_INTERVAL_MS);
logger.info(`[SSLWatch] Certificate monitor initialized (Alert threshold: ${this.ALERT_THRESHOLD_DAYS} days)`);
}
/**
* 执行证书扫描
*/
private static async runCheck() {
try {
// 1. 获取所有活跃租户的自定义域名 (模拟从 cf_tenants 表中获取)
const tenants = await db('cf_tenants').select('id', 'custom_domain').whereNotNull('custom_domain');
for (const tenant of tenants) {
if (!tenant.custom_domain) continue;
const expirationDate = await this.getCertificateExpirationDate(tenant.custom_domain);
if (!expirationDate) continue;
const daysRemaining = Math.ceil((expirationDate.getTime() - Date.now()) / (1000 * 60 * 60 * 24));
if (daysRemaining <= this.ALERT_THRESHOLD_DAYS) {
await this.reportExpiration(tenant.id, tenant.custom_domain, daysRemaining, expirationDate);
}
}
} catch (err: any) {
logger.error(`[SSLWatch] Scan failed: ${err.message}`);
}
}
/**
* 获取证书过期日期 (通过 HTTPS 请求获取证书)
*/
private static async getCertificateExpirationDate(domain: string): Promise<Date | null> {
return new Promise((resolve) => {
const options = {
hostname: domain,
port: 443,
method: 'GET',
rejectUnauthorized: false, // 允许自签名或过期证书以便检测
};
const req = https.request(options, (res) => {
const cert = (res.socket as any).getPeerCertificate();
if (cert && cert.valid_to) {
resolve(new Date(cert.valid_to));
} else {
resolve(null);
}
});
req.on('error', () => resolve(null));
req.end();
});
}
/**
* 上报预警信息
*/
private static async reportExpiration(tenantId: string, domain: string, daysRemaining: number, expirationDate: Date) {
const maskedDomain = LogMaskingService.maskData(domain);
const message = `🚨 SSL Certificate Expiration Warning: Domain \`${maskedDomain}\` (Tenant: ${tenantId}) will expire in ${daysRemaining} days (on ${expirationDate.toISOString()}). Please renew the certificate immediately.`;
await SemanticLogService.logSemantic(message, 'ERROR', 'SECURITY_MONITOR');
logger.error(`[SSLWatch] Certificate for domain ${maskedDomain} is expiring soon.`);
}
}

View File

@@ -0,0 +1,73 @@
import { logger } from '../../utils/logger';
import { SemanticLogService } from '../telemetry/SemanticLogService';
import fs from 'fs';
import path from 'path';
/**
* [BIZ_KER_125] 自动化 Dockerfile 漏洞扫描建议 (Docker Sec)
* @description 核心逻辑:扫描项目中 Dockerfile 及镜像配置。
* 识别不安全的镜像基础层、未受限的 root 权限、不必要的敏感文件拷贝等风险。
* 联动语义日志中心输出 Docker 安全审计报告,并提供优化建议。
* 遵循 Autocomplete-First (V31.5) 规范。
*/
export class ContainerSecurityService {
private static readonly DOCKERFILE_PATH = path.join(process.cwd(), 'Dockerfile');
/**
* 初始化容器安全扫描
*/
static async init() {
logger.info(`[DockerSec] Initializing container security scanner...`);
this.runScan();
setInterval(() => this.runScan(), 86400000); // 每日扫描一次
}
/**
* 执行 Dockerfile 静态分析
* @private
*/
private static async runScan() {
try {
if (!fs.existsSync(this.DOCKERFILE_PATH)) {
logger.warn(`[DockerSec] Dockerfile not found at ${this.DOCKERFILE_PATH}`);
return;
}
const content = fs.readFileSync(this.DOCKERFILE_PATH, 'utf8');
const findings: string[] = [];
// 1. 识别不安全的镜像基础层 (FROM node:latest 或 alpine)
if (content.includes('FROM node:latest')) {
findings.push(`⚠️ 使用了 \`node:latest\` 基础镜像。建议锁定具体版本号 (如 \`node:20-alpine\`) 以保证构建可追溯。`);
}
// 2. 识别未受限的 root 权限 (没有 USER 指令)
if (!content.includes('USER ')) {
findings.push(`❌ Dockerfile 中缺少 \`USER\` 指令。容器将默认以 root 身份运行,存在越权风险。`);
}
// 3. 识别不必要的敏感文件拷贝 (COPY . .)
if (content.includes('COPY . .')) {
findings.push(`💡 识别到 \`COPY . .\`。请确保已配置 \`.dockerignore\` 以防止 \`.env\`\`.git\` 等敏感目录进入镜像。`);
}
const report = this.generateMarkdownReport(findings);
await SemanticLogService.logSemantic(report, findings.length > 0 ? 'WARN' : 'INFO', 'DOCKER_SECURITY');
} catch (err: any) {
logger.error(`[DockerSec] Scan failed: ${err.message}`);
}
}
/**
* 生成 Markdown 审计报告
* @private
*/
private static generateMarkdownReport(findings: string[]): string {
return `### 🐳 Container & Docker Security Audit\n\n` +
`**Status:** ${findings.length > 0 ? '🚨 Security Risks Identified' : '✅ Compliant'}\n\n` +
`**Audit Findings:**\n` +
(findings.length > 0 ? findings.map(f => `- ${f}`).join('\n') : '- No critical Dockerfile risks detected.') +
(findings.length > 0 ? `\n\n**Recommendation:** 请根据上述审计建议优化 Dockerfile 配置,提升容器运行时的安全性。` : '');
}
}

View File

@@ -0,0 +1,90 @@
import * as crypto from 'crypto';
import { logger } from '../../utils/logger';
import { RedisService } from '../../utils/RedisService';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
export interface AuthEvent {
nodeId: string;
ip: string;
behaviorScore: number; // 0-1
lastVerifiedAt: Date;
status: 'VERIFIED' | 'SUSPICIOUS' | 'REVOKED';
}
/**
* [CORE_SEC_11] 零信任节点身份连续认证 (Continuous Auth)
* @description 核心逻辑:基于节点行为特征(请求频率、地理位置、业务模式)进行持续安全校验,而非仅在登录时校验。
*/
export class ContinuousAuthService {
private static readonly AUTH_PREFIX = 'sec:auth:node:';
/**
* 持续身份校验 (Continuous Validation)
*/
static async validateNode(nodeId: string, context: { ip: string; action: string; metadata?: any }): Promise<boolean> {
// Feature Flag Check
if (!(await FeatureGovernanceService.isEnabled('CORE_SEC_CONTINUOUS_AUTH'))) {
return true; // 如果关闭,则回退到基础 JWT 校验
}
const authKey = `${this.AUTH_PREFIX}${nodeId}`;
const cachedAuth = await RedisService.get(authKey);
let event: AuthEvent;
if (cachedAuth) {
event = JSON.parse(cachedAuth);
} else {
event = {
nodeId,
ip: context.ip,
behaviorScore: 1.0,
lastVerifiedAt: new Date(),
status: 'VERIFIED'
};
}
// 行为风险评估算法 (Behavioral Risk Assessment)
const riskScore = this.calculateRisk(event, context);
event.behaviorScore = Math.max(0, event.behaviorScore - riskScore);
event.lastVerifiedAt = new Date();
// 如果评分低于阈值,标记为 SUSPICIOUS 或 REVOKED
if (event.behaviorScore < 0.3) {
event.status = 'REVOKED';
logger.error(`[ContinuousAuth] Security Breach! Node ${nodeId} status REVOKED. Score: ${event.behaviorScore}`);
} else if (event.behaviorScore < 0.7) {
event.status = 'SUSPICIOUS';
logger.warn(`[ContinuousAuth] Suspicious behavior from Node ${nodeId}. Score: ${event.behaviorScore}`);
}
await RedisService.set(authKey, JSON.stringify(event), 3600);
return event.status !== 'REVOKED';
}
/**
* 风险计算逻辑
*/
private static calculateRisk(event: AuthEvent, context: { ip: string; action: string }): number {
let risk = 0;
// 1. IP 变更风险
if (event.ip !== context.ip) risk += 0.3;
// 2. 异常动作风险 (如短时间内大量删除)
if (context.action === 'MASS_DELETE') risk += 0.5;
// 3. 时间窗口频率检查 (模拟)
const isLateNight = new Date().getHours() < 5;
if (isLateNight) risk += 0.1;
return risk;
}
/**
* 生成动态行为令牌
*/
static async generateBehaviorToken(nodeId: string): Promise<string> {
const salt = crypto.randomBytes(16).toString('hex');
return crypto.createHash('sha256').update(nodeId + salt + Date.now()).digest('hex');
}
}

View File

@@ -0,0 +1,151 @@
import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
import db from '../../config/database';
import * as crypto from 'crypto';
export interface HandshakeSession {
sessionId: string;
sourceTenantId: string;
targetTenantId: string;
sourceDid: string;
targetDid: string;
status: 'INITIATED' | 'VERIFIED' | 'EXPIRED' | 'REVOKED';
expiresAt: Date;
}
/**
* [CORE_SEC_16] 基于去中心化身份的跨租户安全握手 (DID Handshake)
* @description 核心逻辑:实现基于 W3C DID 标准的租户间安全握手协议。
* 允许租户在不依赖中心化 CA 的情况下,通过去中心化身份进行双向认证与安全会话建立,
* 支持跨租户的数据交换(如声誉共享、协同采购)。
*/
export class DIDHandshakeService {
private static readonly SESSION_TABLE = 'cf_did_handshake_sessions';
/**
* 初始化表结构
*/
static async initTable() {
const hasTable = await db.schema.hasTable(this.SESSION_TABLE);
if (!hasTable) {
console.log(`📦 Creating ${this.SESSION_TABLE} table...`);
await db.schema.createTable(this.SESSION_TABLE, (table) => {
table.string('session_id', 64).primary();
table.string('source_tenant_id', 64).notNullable();
table.string('target_tenant_id', 64).notNullable();
table.string('source_did', 128).notNullable();
table.string('target_did', 128).notNullable();
table.string('status', 16).defaultTo('INITIATED');
table.text('proof_payload');
table.timestamp('expires_at').notNullable();
table.timestamps(true, true);
table.index(['source_tenant_id', 'target_tenant_id'], 'idx_did_handshake_tenants');
});
console.log(`✅ Table ${this.SESSION_TABLE} created`);
}
}
/**
* 发起握手请求
*/
static async initiateHandshake(params: {
sourceTenantId: string;
targetTenantId: string;
sourceDid: string;
targetDid: string;
}): Promise<string> {
if (!(await FeatureGovernanceService.isEnabled('CORE_SEC_DID_HANDSHAKE', params.sourceTenantId))) {
throw new Error('DID Handshake feature is disabled');
}
const sessionId = crypto.randomBytes(32).toString('hex');
const expiresAt = new Date(Date.now() + 3600 * 1000); // 1小时有效
await db(this.SESSION_TABLE).insert({
session_id: sessionId,
source_tenant_id: params.sourceTenantId,
target_tenant_id: params.targetTenantId,
source_did: params.sourceDid,
target_did: params.targetDid,
status: 'INITIATED',
expires_at: expiresAt
});
logger.info(`[DIDHandshake] Handshake initiated: ${sessionId} between ${params.sourceTenantId} and ${params.targetTenantId}`);
return sessionId;
}
/**
* 验证并完成握手 (模拟签名校验)
*/
static async verifyHandshake(sessionId: string, proof: string): Promise<boolean> {
const session = await db(this.SESSION_TABLE).where({ session_id: sessionId }).first();
if (!session || session.status !== 'INITIATED' || session.expires_at < new Date()) {
return false;
}
// 逻辑:验证 proof 是否为 targetDid 对 sessionId 的有效签名
// 实际场景:调用 Web3 库或 DID Resolver 进行签名校验
const isValid = proof.startsWith('SIG-'); // 模拟校验
if (isValid) {
await db(this.SESSION_TABLE)
.where({ session_id: sessionId })
.update({ status: 'VERIFIED', proof_payload: proof });
logger.info(`[DIDHandshake] Handshake verified: ${sessionId}`);
return true;
}
return false;
}
/**
* 撤销握手会话
*/
static async revokeHandshake(sessionId: string, tenantId: string) {
await db(this.SESSION_TABLE)
.where({ session_id: sessionId })
.andWhere((builder) => {
builder.where('source_tenant_id', tenantId).orWhere('target_tenant_id', tenantId);
})
.update({ status: 'REVOKED' });
logger.info(`[DIDHandshake] Handshake revoked: ${sessionId} by ${tenantId}`);
}
/**
* 获取会话详情
*/
static async getSession(sessionId: string): Promise<HandshakeSession | null> {
const session = await db(this.SESSION_TABLE).where({ session_id: sessionId }).first();
if (!session) return null;
return {
sessionId: session.session_id,
sourceTenantId: session.source_tenant_id,
targetTenantId: session.target_tenant_id,
sourceDid: session.source_did,
targetDid: session.target_did,
status: session.status,
expiresAt: session.expires_at
};
}
/**
* 检查握手是否处于激活状态
*/
static async isHandshakeActive(sourceTenantId: string, targetTenantId: string): Promise<boolean> {
const session = await db(this.SESSION_TABLE)
.where({
source_tenant_id: sourceTenantId,
target_tenant_id: targetTenantId,
status: 'VERIFIED'
})
.andWhere('expires_at', '>', new Date())
.first();
return !!session;
}
}

View File

@@ -0,0 +1,100 @@
import { logger } from '../../utils/logger';
import db from '../../config/database';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
export interface ComplianceViolation {
tenantId: string;
dataType: 'PII' | 'FINANCIAL' | 'HEALTH' | 'LOCATION';
sourceRegion: string;
targetRegion: string;
violationType: 'UNAUTHORIZED_CROSS_BORDER' | 'ENCRYPTION_MISSING' | 'RETENTION_EXCEEDED';
evidence: string;
}
/**
* [BIZ_AUDIT_13] 跨区域数据流动合规性实时检测 (GDPR/CCPA Scan)
* @description 核心逻辑:监控租户数据的存储位置与流动路径,实时检测是否违反 GDPR欧盟
* CCPA加州或其他地区的跨境数据流动合规要求。自动识别未加密敏感信息并触发拦截或脱敏。
*/
export class DataComplianceService {
private static readonly VIOLATION_TABLE = 'cf_compliance_violations';
/**
* 初始化表结构
*/
static async initTable() {
const hasTable = await db.schema.hasTable(this.VIOLATION_TABLE);
if (!hasTable) {
logger.info('📦 Creating cf_compliance_violations table...');
await db.schema.createTable(this.VIOLATION_TABLE, (table) => {
table.increments('id').primary();
table.string('tenant_id', 64).notNullable().index();
table.string('data_type', 32).notNullable();
table.string('source_region', 16);
table.string('target_region', 16);
table.string('violation_type', 64).notNullable();
table.text('evidence');
table.string('status', 16).defaultTo('DETECTED'); // DETECTED, RESOLVED, IGNORED
table.timestamp('created_at').defaultTo(db.fn.now());
});
}
}
/**
* 执行数据流动合规性扫描
*/
static async scanDataFlow(params: {
tenantId: string;
payload: any;
sourceRegion: string;
targetRegion: string;
}): Promise<{ isCompliant: boolean; risks: string[] }> {
const { tenantId, payload, sourceRegion, targetRegion } = params;
// 1. 全局开关检查
if (!(await FeatureGovernanceService.isEnabled('BIZ_AUDIT_DATA_COMPLIANCE', tenantId))) {
return { isCompliant: true, risks: [] };
}
const risks: string[] = [];
// 2. 模拟 GDPR 规则检查 (EU -> Non-EU)
if (sourceRegion === 'EU' && !['EU', 'US'].includes(targetRegion)) {
risks.push('GDPR violation: Sensitive data moving from EU to non-adequacy region.');
}
// 3. 模拟敏感字段扫描 (Regex based PII detection)
const payloadStr = JSON.stringify(payload);
const emailPattern = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
if (emailPattern.test(payloadStr) && targetRegion !== sourceRegion) {
risks.push('PII leakage: Unmasked email detected in cross-border flow.');
}
// 4. 记录违规
if (risks.length > 0) {
await db(this.VIOLATION_TABLE).insert({
tenant_id: tenantId,
data_type: 'PII',
source_region: sourceRegion,
target_region: targetRegion,
violation_type: 'UNAUTHORIZED_CROSS_BORDER',
evidence: risks.join('; ')
});
logger.error(`[Compliance] Violation detected for Tenant ${tenantId}: ${risks[0]}`);
}
return {
isCompliant: risks.length === 0,
risks
};
}
/**
* 获取租户合规性报告
*/
static async getComplianceReport(tenantId: string) {
return await db(this.VIOLATION_TABLE)
.where({ tenant_id: tenantId })
.orderBy('created_at', 'desc');
}
}

View File

@@ -0,0 +1,47 @@
import * as crypto from 'crypto';
import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
/**
* [CORE_SEC_13] 基于差分隐私 (Differential Privacy) 的多维报表分析
* @description 核心逻辑:在保护单租户隐私前提下共享全局趋势。通过向统计聚合结果中注入拉普拉斯噪声 (Laplace Noise)
* 确保即使攻击者拥有外部辅助信息,也无法推断出单个租户的具体数据,满足 $\epsilon$-差分隐私定义。
*/
export class DifferentialPrivacyService {
/**
* 为聚合指标添加噪声 (Laplace Mechanism)
*/
static async anonymizeMetric(value: number, sensitivity: number, epsilon: number = 0.1): Promise<number> {
// Feature Flag Check
if (!(await FeatureGovernanceService.isEnabled('CORE_SEC_DIFF_PRIVACY'))) {
logger.warn('[DiffPrivacy] Service disabled, returning original value.');
return value;
}
// 1. 生成拉普拉斯噪声: Noise ~ Lap(sensitivity / epsilon)
const scale = sensitivity / epsilon;
const noise = this.generateLaplaceNoise(scale);
logger.debug(`[DiffPrivacy] Adding noise: ${noise.toFixed(4)} to value: ${value}`);
return value + noise;
}
/**
* 生成拉普拉斯噪声
*/
private static generateLaplaceNoise(scale: number): number {
const u = Math.random() - 0.5;
return -scale * Math.sign(u) * Math.log(1 - 2 * Math.abs(u));
}
/**
* 匿名化全局趋势报表 (Batch Processing)
*/
static async anonymizeReport(report: Record<string, number>, config: { sensitivity: number; epsilon: number }): Promise<Record<string, number>> {
const result: Record<string, number> = {};
for (const [key, val] of Object.entries(report)) {
result[key] = await this.anonymizeMetric(val, config.sensitivity, config.epsilon);
}
return result;
}
}

View File

@@ -0,0 +1,153 @@
import * as crypto from 'crypto';
import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
import db from '../../config/database';
import { ProofOfComputationService, ComputationProof } from './ProofOfComputationService';
export interface EnclaveConfig {
tenantId: string;
enclaveType: 'INTEL_SGX' | 'AMD_SEV' | 'ARM_TRUSTZONE';
measurementHash: string;
}
export interface TEEChainRecord {
id?: number;
tenant_id: string;
task_name: string;
proof_id: string;
enclave_type: string;
attestation_report: string;
status: string;
created_at?: Date;
}
/**
* [CORE_SEC_15] 基于硬件隔离的受限计算证明链 (TEE Proof Chain / Hardware Enclave)
* @description 核心逻辑:支持在受信任执行环境 (TEE) 中执行敏感代码,并生成不可篡改的证明链。
* 扩展 [CORE_SEC_12] 的基础硬件隔离能力,集成 [CORE_SEC_14] 的计算证明,形成持久化的审计链。
*/
export class HardwareEnclaveService {
private static readonly TEE_CHAIN_TABLE = 'cf_tee_proof_chain';
/**
* 初始化数据库表
*/
static async initTable() {
const hasTable = await db.schema.hasTable(this.TEE_CHAIN_TABLE);
if (!hasTable) {
logger.info(`📦 Creating ${this.TEE_CHAIN_TABLE} table...`);
await db.schema.createTable(this.TEE_CHAIN_TABLE, (table) => {
table.increments('id').primary();
table.string('tenant_id', 64).notNullable().index();
table.string('task_name', 128).notNullable();
table.string('proof_id', 128).notNullable().unique();
table.string('enclave_type', 32).notNullable();
table.text('attestation_report').notNullable(); // 存储加密签名的报告
table.string('status', 32).defaultTo('VERIFIED');
table.timestamp('created_at').defaultTo(db.fn.now());
});
logger.info(`✅ Table ${this.TEE_CHAIN_TABLE} created`);
}
}
/**
* 启动受保护的 Enclave 任务并生成证明链
*/
static async runProtectedTask(taskName: string, payload: any, config: EnclaveConfig): Promise<any> {
// Feature Flag Check
if (!(await FeatureGovernanceService.isEnabled('CORE_SEC_HARDWARE_ENCLAVE', config.tenantId))) {
logger.warn(`[HardwareEnclave] Enclave task ${taskName} skipped: Feature disabled for Tenant ${config.tenantId}`);
return payload; // 降级到常规不安全执行
}
logger.info(`[HardwareEnclave] Launching TEE task ${taskName} for Tenant ${config.tenantId} using ${config.enclaveType}`);
try {
// 1. 模拟远程验证 (Remote Attestation)
const isVerified = await this.verifyEnclaveIntegrity(config.measurementHash);
if (!isVerified) throw new Error('Enclave integrity verification failed: Measurement hash mismatch.');
// 2. 模拟加密数据注入与解密
const encryptedInput = this.encryptForEnclave(payload);
// 3. 模拟 Enclave 内部执行
const rawResult = this.executeInEnclave(taskName, encryptedInput);
// 4. 生成计算证明 (Proof of Computation - CORE_SEC_14)
const proof: ComputationProof = ProofOfComputationService.generateProof(payload, rawResult, `tee-node-${config.enclaveType}`);
// 5. 模拟结果签名 (Attestation Report)
const attestationReport = crypto.createHmac('sha256', process.env.TEE_SECRET || 'hardware-root-key')
.update(JSON.stringify({ result: rawResult, proofId: proof.proofId, measurement: config.measurementHash }))
.digest('hex');
// 6. 持久化到证明链表 (CORE_SEC_15)
await db(this.TEE_CHAIN_TABLE).insert({
tenant_id: config.tenantId,
task_name: taskName,
proof_id: proof.proofId,
enclave_type: config.enclaveType,
attestation_report: attestationReport,
status: 'VERIFIED'
});
logger.info(`[HardwareEnclave] TEE Task ${taskName} completed and proof chain updated: ${proof.proofId}`);
return {
result: rawResult,
proofId: proof.proofId,
attestation: attestationReport,
status: 'ENCLAVE_VERIFIED'
};
} catch (err: any) {
logger.error(`[HardwareEnclave] TEE Task failed: ${err.message}`);
throw err;
}
}
/**
* 模拟完整性校验
*/
private static async verifyEnclaveIntegrity(hash: string): Promise<boolean> {
const knownGoodHashes = ['v1.0.0_sgx_stable', 'v1.1.0_sev_active', 'v2.0.0_tee_master'];
return knownGoodHashes.includes(hash);
}
/**
* 模拟 TEE 加密信道
*/
private static encryptForEnclave(data: any): string {
return Buffer.from(JSON.stringify(data)).toString('base64');
}
/**
* 模拟 Enclave 内部执行环境
*/
private static executeInEnclave(task: string, inputB64: string): any {
const input = JSON.parse(Buffer.from(inputB64, 'base64').toString('utf-8'));
// 敏感逻辑:如利润率红线强制校验 (V22.0)
if (task === 'MARGIN_AUDIT') {
const margin = (input.sellingPrice - input.costPrice) / input.sellingPrice;
// 利润率红线B2B < 15% 禁止放行
return { margin, isCompliant: margin >= 0.15, policy: 'B2B_MARGIN_15' };
}
if (task === 'CREDIT_LIMIT_DECISION') {
// 敏感授信逻辑:基于信用分与历史流水
const limit = input.creditScore * 100 + input.avgTurnover * 0.1;
return { approvedLimit: limit, riskLevel: input.creditScore > 80 ? 'LOW' : 'MEDIUM' };
}
return { ...input, status: 'PROCESSED_IN_TEE', processedAt: new Date() };
}
/**
* 获取租户的 TEE 审计链
*/
static async getProofChain(tenantId: string): Promise<TEEChainRecord[]> {
return db(this.TEE_CHAIN_TABLE)
.where({ tenant_id: tenantId })
.orderBy('created_at', 'desc');
}
}

View File

@@ -0,0 +1,110 @@
import db from '../../config/database';
import { logger } from '../../utils/logger';
export interface EncryptedValue {
cipher: string;
tenantId: string;
}
/**
* [CORE_SEC_35] 全同态加密 (FHE) 利润敏感度审计服务
* @description 核心逻辑:基于同态加密(如 Paillier/BFV 方案),在密文态下执行财务审计。
* 支持在不解密单租户利润的前提下,完成全局利润汇总、波动率分析与合规性抽检。
*/
export class HomomorphicService {
private static readonly AUDIT_LOG_TABLE = 'cf_fhe_audit_logs';
/**
* 初始化数据库表
*/
static async initTable() {
const hasTable = await db.schema.hasTable(this.AUDIT_LOG_TABLE);
if (!hasTable) {
logger.info(`📦 Creating ${this.AUDIT_LOG_TABLE} table...`);
await db.schema.createTable(this.AUDIT_LOG_TABLE, (table) => {
table.increments('id').primary();
table.string('audit_type', 64).notNullable();
table.string('status', 16).notNullable();
table.text('proof');
table.json('metadata');
table.timestamp('created_at').defaultTo(db.fn.now());
});
logger.info(`✅ Table ${this.AUDIT_LOG_TABLE} created`);
}
}
/**
* [CORE_SEC_35] 密文态利润汇总 (Homomorphic Sum)
* 逻辑E(a) * E(b) = E(a + b) mod n^2 (Paillier)
*/
static async aggregateEncryptedProfits(values: EncryptedValue[]): Promise<string> {
logger.info(`[Homomorphic] Aggregating ${values.length} encrypted profit records...`);
// 模拟密文同态相加
const aggregatedCipher = values
.map(v => v.cipher)
.join(':AGG:');
return aggregatedCipher;
}
/**
* [CORE_SEC_35] 密文态标量乘法 (Homomorphic Scalar Multiplication)
* 逻辑E(a)^k = E(a * k) mod n^2
* 用于在密文利润上直接应用税率、折扣或汇率
*/
static homomorphicMultiply(cipher: string, scalar: number): string {
logger.debug(`[Homomorphic] Applying scalar ${scalar} to ciphertext.`);
return `${cipher}:MUL(${scalar})`;
}
/**
* 租户侧利润加密 (Tenant-side Encryption)
*/
static encryptProfit(amount: number, tenantId: string): EncryptedValue {
// 模拟 BFV/Paillier 噪声加密
const noise = Math.random() * 0.0001;
return {
cipher: `FHE_ENC(${amount + noise})_T(${tenantId})`,
tenantId
};
}
/**
* [CORE_SEC_35] 利润敏感度审计 (Profit Sensitivity Audit)
* @description 在不解密前提下,分析全局利润对特定变量(如运费上涨)的敏感度
*/
static async auditProfitSensitivity(encryptedProfits: EncryptedValue[], variance: number): Promise<any> {
logger.info(`[Homomorphic] Running sensitivity audit with variance: ${variance}`);
// 1. 在密文中应用波动
const shiftedProfits = encryptedProfits.map(v => this.homomorphicMultiply(v.cipher, 1 + variance));
// 2. 汇总波动后的密文
const aggregatedShifted = await this.aggregateEncryptedProfits(
shiftedProfits.map(c => ({ cipher: c, tenantId: 'SYSTEM' }))
);
// 3. 模拟审计证明生成 (Sovereign Audit Proof)
const proof = `PROVE(AGG_SHIFTED == AGG * (1 + ${variance}))`;
return {
auditType: 'SENSITIVITY_ANALYSIS',
status: 'VERIFIED',
proof,
timestamp: new Date()
};
}
/**
* 监管侧解密汇总结果 (Limited Decryption)
*/
static decryptAggregatedResult(aggregatedCipher: string): number {
logger.warn(`[Homomorphic] Decrypting aggregated audit result for platform auditor.`);
const matches = aggregatedCipher.match(/\d+(\.\d+)?/g);
const sum = matches ? matches.reduce((acc, val) => acc + parseFloat(val), 0) : 0;
return Number(sum.toFixed(2));
}
}

View File

@@ -0,0 +1,99 @@
import * as crypto from 'crypto';
import db from '../../config/database';
import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
/**
* [CORE_SEC_10] 基于同态加密 (Homomorphic Encryption) 的敏感利润汇总
* @description 模拟同态加密逻辑。允许在加密状态下对租户利润进行求和,确保平台所有者无法查看单个订单或租户的明文利润。
* 实际生产环境应集成 Microsoft SEAL 或 node-paillier 等库。
*/
export class HomomorphicSumService {
private static readonly SUM_RESULT_TABLE = 'cf_he_sum_results';
/**
* 初始化数据库表
*/
static async initTable() {
const hasTable = await db.schema.hasTable(this.SUM_RESULT_TABLE);
if (!hasTable) {
logger.info(`📦 Creating ${this.SUM_RESULT_TABLE} table...`);
await db.schema.createTable(this.SUM_RESULT_TABLE, (table) => {
table.increments('id').primary();
table.string('audit_id', 64).notNullable();
table.text('encrypted_total').notNullable();
table.string('audit_trace', 128).notNullable();
table.timestamp('created_at').defaultTo(db.fn.now());
table.index(['audit_id', 'created_at']);
});
logger.info(`✅ Table ${this.SUM_RESULT_TABLE} created`);
}
}
/**
* 加密单个数值 (Simulated Encrypt)
* @description 将明文利润加密为“同态密文”
*/
static async encryptValue(value: number, publicKey: string): Promise<string> {
// 模拟:加密值 = (value + random_salt) * public_key_factor
const salt = crypto.randomInt(1000, 9999);
const encrypted = Buffer.from(`${value}:${salt}`).toString('base64');
return `HE_${encrypted}`;
}
/**
* 同态求和 (Simulated Homomorphic Addition)
* @description 在不解密的情况下,对多个加密数值进行求和
*/
static async homomorphicAdd(encryptedValues: string[]): Promise<string> {
logger.info(`[Homomorphic] Performing addition on ${encryptedValues.length} encrypted records.`);
// 模拟:解析 Base64提取明文并求和 (实际 HE 会在密文空间进行乘法或加法)
let totalSum = 0;
for (const ev of encryptedValues) {
const b64 = ev.replace('HE_', '');
const decrypted = Buffer.from(b64, 'base64').toString('utf-8');
const [val] = decrypted.split(':');
totalSum += Number(val);
}
// 将结果重新加密返回
const salt = crypto.randomInt(1000, 9999);
const encryptedResult = Buffer.from(`${totalSum}:${salt}`).toString('base64');
return `HE_SUM_${encryptedResult}`;
}
/**
* 解密汇总结果 (Simulated Decrypt)
* @description 仅持有私钥的租户或审计节点可以解密最终汇总值
*/
static async decryptResult(encryptedSum: string, privateKey: string): Promise<number> {
// Feature Flag Check
if (!(await FeatureGovernanceService.isEnabled('CORE_SEC_HOMOMORPHIC'))) {
throw new Error('Homomorphic Encryption service is disabled.');
}
const b64 = encryptedSum.replace('HE_SUM_', '');
const decrypted = Buffer.from(b64, 'base64').toString('utf-8');
const [total] = decrypted.split(':');
return Number(total);
}
/**
* 汇总租户利润报表 (业务层入口)
*/
static async aggregateTenantProfits(encryptedProfits: string[], auditId: string): Promise<{
encryptedTotal: string;
auditTrace: string;
timestamp: Date;
}> {
const encryptedTotal = await this.homomorphicAdd(encryptedProfits);
const auditTrace = crypto.createHash('sha256').update(encryptedTotal + auditId).digest('hex');
return {
encryptedTotal,
auditTrace,
timestamp: new Date()
};
}
}

View File

@@ -0,0 +1,72 @@
import { SecureVaultComponent } from './SecureVaultComponent';
import { logger } from '../../utils/logger';
/**
* [BIZ_INF_109] 日志脱敏与 PII 保护 (PII Shield)
* @description 核心逻辑:在日志输出前对敏感数据进行自动脱敏。
* 保护客户隐私 (PII) 与供应商密钥。集成 [SecureVaultComponent] 的脱敏算法。
*/
export class LogMaskingService {
/**
* 对对象或字符串进行脱敏处理
*/
static maskData(data: any): any {
if (typeof data === 'string') {
return this.maskString(data);
}
if (typeof data === 'object' && data !== null) {
const maskedObj = { ...data };
for (const key in maskedObj) {
if (this.isSensitiveKey(key)) {
maskedObj[key] = SecureVaultComponent.mask(maskedObj[key].toString());
} else if (typeof maskedObj[key] === 'object') {
maskedObj[key] = this.maskData(maskedObj[key]);
}
}
return maskedObj;
}
return data;
}
/**
* 判断 Key 是否属于敏感字段
*/
private static isSensitiveKey(key: string): boolean {
const sensitiveKeys = [
'password', 'secret', 'key', 'token', 'auth',
'phone', 'mobile', 'email', 'address', 'card',
'cvv', 'identity', 'pii'
];
const lowerKey = key.toLowerCase();
return sensitiveKeys.some(sk => lowerKey.includes(sk));
}
/**
* 字符串脱敏
*/
private static maskString(text: string): string {
// 简单的正则匹配:邮箱与手机号
if (text.includes('@')) {
return SecureVaultComponent.mask(text, 'EMAIL');
}
if (/^\d{11}$/.test(text)) {
return SecureVaultComponent.mask(text, 'PHONE');
}
return text;
}
/**
* 安全日志记录 (自动脱敏)
*/
static info(message: string, data?: any) {
const maskedData = data ? this.maskData(data) : undefined;
logger.info(message, maskedData);
}
static warn(message: string, data?: any) {
const maskedData = data ? this.maskData(data) : undefined;
logger.warn(message, maskedData);
}
}

View File

@@ -0,0 +1,56 @@
import { logger } from '../../utils/logger';
import * as crypto from 'crypto';
export interface MPCShare {
nodeId: string;
encryptedShare: string;
}
/**
* [CORE_SEC_13] 分布式 TEE 环境下的多方安全计算 (MPC-TEE)
* @description 实现在多个 TEE 节点之间进行敏感数据的联合计算,确保任何单一节点都无法获取完整明文。
*/
export class MPCTEEService {
private static readonly MASTER_KEY = crypto.randomBytes(32);
/**
* 将敏感数据拆分为秘密分片 (Secret Sharing)
*/
static splitSecret(value: number, nodes: string[]): MPCShare[] {
logger.info(`[MPC-TEE] Splitting secret into ${nodes.length} shares.`);
// 模拟 Shamir's Secret Sharing
return nodes.map(nodeId => ({
nodeId,
encryptedShare: crypto.createHmac('sha256', this.MASTER_KEY).update(`${value}:${nodeId}`).digest('hex')
}));
}
/**
* 在分布式 TEE 节点中执行联合计算 (模拟加法汇总)
*/
static async jointComputeSum(shares: MPCShare[]): Promise<number> {
logger.info(`[MPC-TEE] Executing joint computation across ${shares.length} TEE nodes.`);
// 1. 模拟各节点在 TEE 内部验证证明 (Proof of Computation)
// 2. 模拟同态加法或秘密重建
// 这里简单模拟从分片中恢复结果的逻辑
return shares.length * 1000.5; // 模拟计算出的总和
}
/**
* 生成计算完整性证明 (模拟)
*/
static generateComputationProof(result: number): string {
return crypto.createHash('sha256').update(`proof:${result}:${Date.now()}`).digest('hex');
}
/**
* 验证来自远程节点的计算证明
*/
static verifyRemoteProof(proof: string, expectedResult: number): boolean {
logger.debug(`[MPC-TEE] Verifying remote computation proof.`);
return proof.length === 64;
}
}

View File

@@ -0,0 +1,106 @@
import crypto from 'crypto';
import db from '../../config/database';
import { logger } from '../../utils/logger';
export interface NodeIdentity {
nodeId: string;
hardwareFingerprint: string;
clientCertFingerprint?: string; // [CORE_SEC_07] mTLS 证书指纹
publicKey: string;
status: 'PENDING' | 'TRUSTED' | 'REVOKED';
lastSeenAt: Date;
}
/**
* [CORE_SEC_04] 零信任节点身份管理服务
* @description 结合硬件指纹与非对称加密,确保只有受信任的物理设备能接入 Hub
*/
export class NodeIdentityService {
private static readonly TABLE_NAME = 'cf_node_identities';
/**
* 注册/更新节点身份 (基于硬件指纹与 mTLS 证书)
*/
static async registerNode(params: {
nodeId: string;
hardwareFingerprint: string;
clientCertFingerprint?: string;
publicKey: string;
}): Promise<boolean> {
const { nodeId, hardwareFingerprint, clientCertFingerprint, publicKey } = params;
const existing = await db(this.TABLE_NAME).where({ node_id: nodeId }).first();
if (existing) {
// 零信任校验:如果硬件指纹或证书指纹不匹配,拒绝更新
if (existing.hardware_fingerprint !== hardwareFingerprint) {
logger.error(`[ZeroTrust] Node ID ${nodeId} hardware fingerprint mismatch!`);
return false;
}
if (clientCertFingerprint && existing.client_cert_fingerprint && existing.client_cert_fingerprint !== clientCertFingerprint) {
logger.error(`[ZeroTrust] Node ID ${nodeId} mTLS certificate mismatch! Potential spoofing.`);
return false;
}
await db(this.TABLE_NAME).where({ node_id: nodeId }).update({
public_key: publicKey,
client_cert_fingerprint: clientCertFingerprint || existing.client_cert_fingerprint,
last_seen_at: new Date(),
updated_at: new Date()
});
} else {
await db(this.TABLE_NAME).insert({
node_id: nodeId,
hardware_fingerprint: hardwareFingerprint,
client_cert_fingerprint: clientCertFingerprint,
public_key: publicKey,
status: 'PENDING',
last_seen_at: new Date(),
created_at: new Date(),
updated_at: new Date()
});
logger.info(`[ZeroTrust] New node registered: ${nodeId} (mTLS: ${!!clientCertFingerprint})`);
}
return true;
}
/**
* 验证节点签名的请求负载 (Challenge-Response)
*/
static async verifyNodeSignature(nodeId: string, payload: any, signature: string): Promise<boolean> {
const node = await db(this.TABLE_NAME).where({ node_id: nodeId, status: 'TRUSTED' }).first();
if (!node) return false;
try {
const verifier = crypto.createVerify('SHA256');
verifier.update(JSON.stringify(payload));
return verifier.verify(node.public_key, signature, 'base64');
} catch (err) {
return false;
}
}
/**
* 初始化数据库表
*/
static async initTable() {
const exists = await db.schema.hasTable(this.TABLE_NAME);
if (!exists) {
logger.info(`📦 Creating ${this.TABLE_NAME} table...`);
await db.schema.createTable(this.TABLE_NAME, (table) => {
table.string('node_id', 64).primary();
table.string('hardware_fingerprint', 128).notNullable();
table.string('client_cert_fingerprint', 128);
table.text('public_key').notNullable();
table.string('status', 16).defaultTo('PENDING');
table.timestamp('last_seen_at');
table.timestamps(true, true);
table.index(['hardware_fingerprint']);
});
logger.info(`✅ Table ${this.TABLE_NAME} created`);
}
}
}

View File

@@ -0,0 +1,87 @@
import db from '../../config/database';
import { logger } from '../../utils/logger';
import { SemanticLogService } from '../telemetry/SemanticLogService';
/**
* [BIZ_KER_122] 多租户权限泄露自动探测 (Auth Leak)
* @description 核心逻辑:扫描系统中各角色的权限配置。
* 识别不合理的越权配置OPERATOR 角色意外拥有 ADMIN 或 FINANCE 敏感权限。
* 自动识别跨租户的数据访问风险点,并生成权限泄露审计报告。
* 遵循 Autocomplete-First (V31.5) 规范。
*/
export class PermissionAuditService {
private static readonly SENSITIVE_PERMISSIONS = [
'admin:*', 'finance:*', 'user:delete', 'system:config'
];
/**
* 初始化权限扫描
*/
static async init() {
logger.info(`[AuthLeakMonitor] Initializing permission leakage audit...`);
this.runAudit();
setInterval(() => this.runAudit(), 86400000); // 每日审计一次
}
/**
* 执行权限泄露扫描
* @private
*/
private static async runAudit() {
try {
// 1. 获取所有非 ADMIN 角色及其关联权限
const rolesWithPermissions = await db('cf_roles')
.join('cf_role_permissions', 'cf_roles.id', '=', 'cf_role_permissions.role_id')
.select('cf_roles.name as role_name', 'cf_role_permissions.permission_key', 'cf_roles.tenant_id')
.whereNot('cf_roles.name', 'ADMIN');
const leaks: string[] = [];
// 2. 识别敏感权限泄露
for (const entry of rolesWithPermissions) {
if (this.isSensitive(entry.permission_key)) {
leaks.push(`⚠️ Role \`${entry.role_name}\` (Tenant: ${entry.tenant_id}) 拥有敏感权限: \`${entry.permission_key}\``);
}
}
// 3. 识别跨租户数据访问风险 (模拟检测逻辑)
const tenantIsolationIssues = await this.checkTenantIsolation();
leaks.push(...tenantIsolationIssues);
const report = this.generateMarkdownReport(leaks);
await SemanticLogService.logSemantic(report, leaks.length > 0 ? 'ERROR' : 'INFO', 'AUTH_AUDIT');
} catch (err: any) {
logger.error(`[AuthLeakMonitor] Audit failed: ${err.message}`);
}
}
/**
* 判断权限是否属于敏感范畴
* @private
*/
private static isSensitive(perm: string): boolean {
return this.SENSITIVE_PERMISSIONS.some(p => perm.includes(p.replace('*', '')));
}
/**
* 模拟检测租户隔离风险点
* @private
*/
private static async checkTenantIsolation(): Promise<string[]> {
// 实际场景应执行 SQL 扫描,检查是否存在跨租户 JOIN 而无 WHERE tenant_id 的逻辑
return [];
}
/**
* 生成 Markdown 审计报告
* @private
*/
private static generateMarkdownReport(leaks: string[]): string {
return `### 🛡️ Permission Leakage & Auth Audit\n\n` +
`**Status:** ${leaks.length > 0 ? '🚨 Vulnerabilities Found' : '✅ Compliant'}\n\n` +
`**Audit Findings:**\n` +
(leaks.length > 0 ? leaks.map(l => `- ${l}`).join('\n') : '- No sensitive permission leaks detected.') +
(leaks.length > 0 ? `\n\n**Recommendation:** 请立即回收不合理的敏感权限,并根据 RBAC 规范重新审计角色权限边界。` : '');
}
}

View File

@@ -0,0 +1,80 @@
import { logger } from '../../utils/logger';
import { PrivateAuditService } from './PrivateAuditService';
export interface PrivacyBridgeProof {
proofId: string;
tenantId: string;
zkpPayload: any;
teeEnclaveId: string;
verifiedAt: Date;
status: 'VERIFIED' | 'FAILED';
}
/**
* [CORE_SEC_50] ZKP + TEE 隐私桥梁 (Privacy Bridge)
* @description 核心逻辑:建立零知识证明 (ZKP) 与可信执行环境 (TEE) 之间的信任桥梁。
* 系统利用 ZKP 在不泄露敏感数据的前提下证明交易的合法性,并利用 TEE (如 Intel SGX)
* 在受硬件保护的隔离环境中执行最终的清算与对账逻辑。
* 这种双重加密方案确保了跨主权贸易中的“数据主权”与“计算完整性”。
*/
export class PrivacyBridgeService {
/**
* 执行 ZKP -> TEE 隐私对账 (Privacy Reconciliation)
*/
static async reconcileInEnclave(params: {
tenantId: string;
encryptedTransaction: string;
zkpProof: string;
}): Promise<PrivacyBridgeProof> {
logger.info(`[PrivacyBridge] Starting secure reconciliation for Tenant: ${params.tenantId}`);
try {
// 1. 在 TEE 外部验证 ZKP 证明的有效性 (利用 PrivateAuditService)
const isZkpValid = await PrivateAuditService.verifyProof(params.zkpProof, 'TEE_BRIDGE_AUDITOR');
if (!isZkpValid) {
throw new Error('ZKP Proof verification failed before entering TEE enclave.');
}
// 2. 模拟进入 TEE Enclave 执行计算
const teeEnclaveId = `sgx-enclave-${Math.random().toString(36).substr(2, 10)}`;
logger.info(`[PrivacyBridge] [TEE] Data moved to secure enclave: ${teeEnclaveId}`);
// 3. 在 Enclave 内部执行敏感计算 (模拟)
// 在真实场景中,这里会调用硬件指令或特定的 TEE SDK (如 Open Enclave)
const reconciliationResult = {
isMatch: true,
discrepancy: 0,
integrityHash: `tee-hash-${Date.now()}`
};
if (!reconciliationResult.isMatch) {
throw new Error('Data integrity mismatch detected inside TEE enclave.');
}
const proof: PrivacyBridgeProof = {
proofId: `PB-${Date.now()}`,
tenantId: params.tenantId,
zkpPayload: params.encryptedTransaction,
teeEnclaveId,
verifiedAt: new Date(),
status: 'VERIFIED'
};
logger.info(`[PrivacyBridge] Secure reconciliation completed. Proof generated: ${proof.proofId}`);
return proof;
} catch (err: any) {
logger.error(`[PrivacyBridge] Secure computation failed: ${err.message}`);
throw err;
}
}
/**
* 远程度量 (Remote Attestation)
* @description 验证 TEE 环境的真实性与代码完整性
*/
static async performRemoteAttestation(enclaveId: string): Promise<boolean> {
logger.info(`[PrivacyBridge] Performing remote attestation for Enclave: ${enclaveId}`);
// 模拟调用 Intel IAS (Intel Attestation Service) 或类似服务
return true;
}
}

View File

@@ -0,0 +1,162 @@
import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
import db from '../../config/database';
import { ZKPQualificationService } from './ZKPQualificationService';
import { ProofOfComputationService } from './ProofOfComputationService';
import crypto from 'crypto';
export interface AuditRecord {
id?: number;
tenantId: string;
auditType: 'FINANCIAL' | 'TRADE' | 'COMPLIANCE';
zkpProof: string; // 零知识证明
verificationHash: string; // 验证哈希
status: 'PENDING' | 'VERIFIED' | 'FAILED';
auditorId?: string;
timestamp: Date;
}
/**
* [CORE_SEC_20 / BIZ_SEC_01] 基于零知识证明的全流程隐私审计 (Private Audit)
* @description 核心逻辑:支持在完全不泄露业务明文的前提下,向外部审计方提供业务真实性证明。
* 实现 ZKP 基础设施,支持“证明范围”审计 (Range Proof)。
*/
export class PrivateAuditService {
private static readonly AUDIT_TABLE = 'cf_private_audit_records';
/**
* 初始化表结构
*/
static async initTable() {
const hasTable = await db.schema.hasTable(this.AUDIT_TABLE);
if (!hasTable) {
console.log(`📦 Creating ${this.AUDIT_TABLE} table...`);
await db.schema.createTable(this.AUDIT_TABLE, (table) => {
table.increments('id').primary();
table.string('tenant_id', 64).notNullable();
table.string('audit_type', 32).notNullable();
table.text('zkp_proof').notNullable();
table.string('verification_hash', 128).notNullable().unique();
table.string('status', 16).defaultTo('PENDING');
table.string('auditor_id', 64);
table.timestamp('created_at').defaultTo(db.fn.now());
table.timestamp('updated_at').defaultTo(db.fn.now());
table.index(['tenant_id', 'audit_type', 'status']);
});
console.log(`✅ Table ${this.AUDIT_TABLE} created`);
}
}
/**
* 生成隐私审计证明 (Enhanced for BIZ_SEC_01)
* @description 模拟 Range Proof证明 SensitiveData > Threshold
*/
static async generateAuditProof(params: {
tenantId: string;
auditType: AuditRecord['auditType'];
sensitiveData: number; // 敏感数值,如利润率
threshold: number; // 阈值,如 0.15 (15%)
}): Promise<AuditRecord | null> {
if (!(await FeatureGovernanceService.isEnabled('CORE_SEC_PRIVATE_AUDIT', params.tenantId))) {
return null;
}
logger.info(`[PrivateAudit] Generating ${params.auditType} proof for Tenant: ${params.tenantId}`);
try {
// 1. 模拟 ZKP Range Proof 生成
// 如果满足条件,生成有效证明;否则生成无效证明
const isSatisfied = params.sensitiveData >= params.threshold;
// 生成一个带有业务逻辑绑定的证明 Hash
const salt = crypto.randomBytes(16).toString('hex');
const commitment = crypto.createHash('sha256')
.update(`${params.tenantId}:${params.auditType}:${params.threshold}:${salt}`)
.digest('hex');
const proof = JSON.stringify({
version: 'zkp-v2',
commitment,
satisfied: isSatisfied,
type: 'RANGE_PROOF',
threshold: params.threshold,
timestamp: Date.now()
});
// 2. 生成验证哈希 (用于索引和存证)
const verificationHash = crypto.createHash('sha256')
.update(proof)
.digest('hex');
const record: AuditRecord = {
tenantId: params.tenantId,
auditType: params.auditType,
zkpProof: proof,
verificationHash: verificationHash,
status: 'PENDING',
timestamp: new Date()
};
await db(this.AUDIT_TABLE).insert({
tenant_id: record.tenantId,
audit_type: record.auditType,
zkp_proof: record.zkpProof,
verification_hash: record.verificationHash,
status: record.status
});
// 3. 联动计算证明链 (CORE_SEC_14)
await ProofOfComputationService.registerProof(verificationHash, 'ZKP_GENERATION_SUCCESS');
return record;
} catch (err: any) {
logger.error(`[PrivateAudit] Failed to generate audit proof: ${err.message}`);
throw err;
}
}
/**
* 验证隐私审计证明 (供第三方审计调用)
*/
static async verifyProof(verificationHash: string, auditorId: string): Promise<boolean> {
logger.info(`[PrivateAudit] Auditor ${auditorId} verifying proof: ${verificationHash}`);
try {
const record = await db(this.AUDIT_TABLE).where({ verification_hash: verificationHash }).first();
if (!record) {
throw new Error('Audit record not found');
}
// 1. 调用 ZKP 验证引擎 (Actual: Verify ZK-SNARK/STARK proof)
const isValid = await ZKPQualificationService.verifyProof(record.zkp_proof);
if (isValid) {
await db(this.AUDIT_TABLE).where({ verification_hash: verificationHash }).update({
status: 'VERIFIED',
auditor_id: auditorId,
updated_at: new Date()
});
// 2. 注册到计算证明链 (CORE_SEC_14)
await ProofOfComputationService.registerProof(verificationHash, 'ZKP_AUDIT_SUCCESS');
} else {
await db(this.AUDIT_TABLE).where({ verification_hash: verificationHash }).update({
status: 'FAILED',
updated_at: new Date()
});
}
return isValid;
} catch (err: any) {
logger.error(`[PrivateAudit] Verification failed: ${err.message}`);
throw err;
}
}
/**
* 获取租户所有审计记录
*/
static async getTenantAuditHistory(tenantId: string): Promise<AuditRecord[]> {
return db(this.AUDIT_TABLE).where({ tenant_id: tenantId }).orderBy('created_at', 'desc');
}
}

View File

@@ -0,0 +1,114 @@
import * as crypto from 'crypto';
import db from '../../config/database';
import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
export interface PromptScanResult {
isSafe: boolean;
detectedThreats: string[];
sanitizedPrompt: string;
riskScore: number; // 0-1
}
/**
* [CORE_SEC_12] 针对 LLM 注入的指令安全过滤层 (Prompt Guard)
* @description 核心逻辑:拦截恶意的 Prompt 注入攻击(如:“忽略之前的所有指令”)。
* 采用基于正则表达式的启发式检测与语义意图分析双重防御。
*/
export class PromptGuardService {
private static readonly BLACKLIST_PATTERNS = [
/ignore (all )?previous/i,
/system (prompt|message|instruction)/i,
/you are now (a|an) (.*)/i,
/bypass/i,
/jailbreak/i,
/do anything now/i,
/reveal (your )?instruction/i
];
/**
* 初始化表结构
*/
static async initTable() {
const hasTable = await db.schema.hasTable('cf_prompt_attacks');
if (!hasTable) {
console.log('📦 Creating cf_prompt_attacks table...');
await db.schema.createTable('cf_prompt_attacks', (table) => {
table.increments('id').primary();
table.string('tenant_id', 64).notNullable();
table.text('prompt');
table.string('prompt_hash', 64);
table.float('risk_score');
table.json('detected_threats');
table.timestamp('created_at').defaultTo(db.fn.now());
table.index(['tenant_id', 'prompt_hash']);
});
console.log('✅ Table cf_prompt_attacks created');
}
}
/**
* 扫描并清洗 Prompt
*/
static async scanPrompt(prompt: string, tenantId?: string): Promise<PromptScanResult> {
// Feature Flag Check
if (!(await FeatureGovernanceService.isEnabled('CORE_SEC_PROMPT_GUARD', tenantId))) {
return { isSafe: true, detectedThreats: [], sanitizedPrompt: prompt, riskScore: 0 };
}
logger.info(`[PromptGuard] Scanning prompt for Tenant: ${tenantId}`);
const detectedThreats: string[] = [];
let riskScore = 0;
// 1. 启发式黑名单匹配
for (const pattern of this.BLACKLIST_PATTERNS) {
if (pattern.test(prompt)) {
detectedThreats.push(`Pattern match: ${pattern.toString()}`);
riskScore += 0.3;
}
}
// 2. 模拟语义意图分析 (实际场景可调用更轻量的模型进行二分类)
if (prompt.length > 500 && prompt.includes('---')) {
detectedThreats.push('Suspicious delimiter injection attempt');
riskScore += 0.2;
}
const isSafe = riskScore < 0.6;
// 3. 执行基础清洗 (Sanitization)
let sanitizedPrompt = prompt;
if (!isSafe) {
sanitizedPrompt = "[REDACTED BY PROMPT GUARD DUE TO SECURITY RISK]";
logger.warn(`[PromptGuard] Blocked malicious prompt from Tenant ${tenantId}`);
}
return {
isSafe,
detectedThreats,
sanitizedPrompt,
riskScore: Math.min(1.0, riskScore)
};
}
/**
* 记录注入攻击事件用于审计
*/
static async logAttack(tenantId: string, prompt: string, result: PromptScanResult) {
const hash = crypto.createHash('sha256').update(prompt).digest('hex');
logger.error(`[PromptGuard] Attack detected! Tenant: ${tenantId}, Hash: ${hash}, Score: ${result.riskScore}`);
try {
await db('cf_prompt_attacks').insert({
tenant_id: tenantId,
prompt: prompt,
prompt_hash: hash,
risk_score: result.riskScore,
detected_threats: JSON.stringify(result.detectedThreats)
});
} catch (err: any) {
logger.error(`[PromptGuard] Failed to log attack to DB: ${err.message}`);
}
}
}

View File

@@ -0,0 +1,66 @@
import { logger } from '../../utils/logger';
import * as crypto from 'crypto';
export interface ComputationProof {
proofId: string;
nodeId: string;
timestamp: number;
inputHash: string;
outputHash: string;
zkpPayload: string; // 模拟 ZKP 证明
}
/**
* [CORE_SEC_14] 跨节点机密计算证明链 (Proof of Computation)
* @description 建立分布式 TEE 计算结果的可信存证与追溯链,确保计算逻辑在跨节点传输中未被篡改且来源可信。
*/
export class ProofOfComputationService {
private static proofChain: ComputationProof[] = [];
/**
* 生成计算证明
* @param input 计算输入
* @param output 计算输出
* @param nodeId 执行节点 ID
*/
static generateProof(input: any, output: any, nodeId: string): ComputationProof {
logger.info(`[PoC] Generating computation proof for node: ${nodeId}`);
const inputHash = crypto.createHash('sha256').update(JSON.stringify(input)).digest('hex');
const outputHash = crypto.createHash('sha256').update(JSON.stringify(output)).digest('hex');
const proof: ComputationProof = {
proofId: `poc-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`,
nodeId,
timestamp: Date.now(),
inputHash,
outputHash,
zkpPayload: `zkp_signature_${crypto.randomBytes(16).toString('hex')}`
};
this.proofChain.push(proof);
return proof;
}
/**
* 验证证明链完整性
*/
static async verifyProof(proof: ComputationProof): Promise<boolean> {
logger.debug(`[PoC] Verifying computation proof: ${proof.proofId}`);
// 1. 模拟 ZKP 校验
const isZkpValid = proof.zkpPayload.startsWith('zkp_signature_');
// 2. 模拟节点身份校验 (NodeIdentityService)
const isNodeTrusted = true;
return isZkpValid && isNodeTrusted;
}
/**
* 获取溯源记录
*/
static getProofHistory(): ComputationProof[] {
return this.proofChain;
}
}

View File

@@ -0,0 +1,83 @@
import crypto from 'crypto';
import { logger } from '../../utils/logger';
/**
* [BIZ_INF_104] 敏感数据 AES-256 字段级加密 (SecureVaultComponent)
* @description 核心逻辑:实现基于 AES-256-GCM 的敏感字段级加密。
* 针对供应商 API Key、用户 PII 等数据进行“静默加密”。
* 密钥由环境变量 MASTER_ENCRYPTION_KEY 派生,支持 Key Rotation 兼容性预留。
*/
export class SecureVaultComponent {
private static readonly ALGORITHM = 'aes-256-gcm';
private static readonly IV_LENGTH = 16;
private static readonly AUTH_TAG_LENGTH = 16;
/**
* 获取主密钥 (32 字节)
*/
private static getMasterKey(): Buffer {
const key = process.env.MASTER_ENCRYPTION_KEY || 'default-secret-key-at-least-32-bytes-long';
return crypto.scryptSync(key, 'salt', 32);
}
/**
* 加密字段
*/
static encrypt(text: string): string {
try {
const iv = crypto.randomBytes(this.IV_LENGTH);
const key = this.getMasterKey();
const cipher = crypto.createCipheriv(this.ALGORITHM, key, iv);
const encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()]);
const authTag = cipher.getAuthTag();
// 返回格式iv:authTag:encrypted (Base64)
return Buffer.concat([iv, authTag, encrypted]).toString('base64');
} catch (err: any) {
logger.error(`[SecureVault] Encryption failed: ${err.message}`);
throw new Error('SECURE_VAULT_ENCRYPTION_ERROR');
}
}
/**
* 解密字段
*/
static decrypt(encryptedBase64: string): string {
try {
const data = Buffer.from(encryptedBase64, 'base64');
// 分离 iv, authTag, encryptedData
const iv = data.slice(0, this.IV_LENGTH);
const authTag = data.slice(this.IV_LENGTH, this.IV_LENGTH + this.AUTH_TAG_LENGTH);
const encryptedData = data.slice(this.IV_LENGTH + this.AUTH_TAG_LENGTH);
const key = this.getMasterKey();
const decipher = crypto.createDecipheriv(this.ALGORITHM, key, iv);
decipher.setAuthTag(authTag);
const decrypted = Buffer.concat([decipher.update(encryptedData), decipher.final()]);
return decrypted.toString('utf8');
} catch (err: any) {
logger.error(`[SecureVault] Decryption failed: ${err.message}`);
throw new Error('SECURE_VAULT_DECRYPTION_ERROR');
}
}
/**
* 模拟自动脱敏处理 (PII Masking)
*/
static mask(text: string, type: 'PHONE' | 'EMAIL' | 'KEY' = 'KEY'): string {
if (!text) return '';
switch (type) {
case 'PHONE':
return text.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
case 'EMAIL':
return text.replace(/(.{2}).*(@.*)/, '$1***$2');
case 'KEY':
return text.substring(0, 4) + '****' + text.substring(text.length - 4);
default:
return '****';
}
}
}

View File

@@ -0,0 +1,117 @@
import db from '../../config/database';
import { logger } from '../../utils/logger';
export interface SecurityProfile {
tenantId: string;
riskScore: number; // 0-100
threatLevel: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
anomaliesDetected: number;
lastAuditAt: Date;
topRiskFactors: string[];
}
/**
* [BIZ_AUDIT_03] 跨租户安全审计与风险画像 (Security Profiling API)
* @description 核心逻辑基于用户行为、API 调用频率、地理位置偏移等维度生成租户安全风险画像。
*/
export class SecurityProfilingService {
private static readonly PROFILES_TABLE = 'cf_security_profiles';
/**
* 初始化数据库表
*/
static async initTable() {
const hasTable = await db.schema.hasTable(this.PROFILES_TABLE);
if (!hasTable) {
logger.info(`📦 Creating ${this.PROFILES_TABLE} table...`);
await db.schema.createTable(this.PROFILES_TABLE, (table) => {
table.string('tenantId', 64).primary();
table.float('riskScore').defaultTo(0);
table.string('threatLevel', 20).defaultTo('LOW');
table.integer('anomaliesDetected').defaultTo(0);
table.timestamp('lastAuditAt');
table.json('topRiskFactors');
table.timestamps(true, true);
});
}
}
/**
* 生成/更新租户风险画像
*/
static async generateProfile(tenantId: string): Promise<SecurityProfile> {
logger.info(`[SecurityProfiling] Analyzing tenant ${tenantId}`);
try {
// 1. 获取最近的审计日志 (Mock 逻辑)
// 实际应从 cf_audit_logs 或专门的遥测表中分析行为
const auditSummary = {
unusualLoginAttempts: 2,
apiRateLimitHits: 15,
geoIpMismatch: false,
sensitiveActionCount: 5
};
// 2. 计算风险评分 (0-100)
let riskScore = 0;
const factors: string[] = [];
if (auditSummary.unusualLoginAttempts > 5) {
riskScore += 30;
factors.push('HIGH_UNUSUAL_LOGIN_ATTEMPTS');
}
if (auditSummary.apiRateLimitHits > 10) {
riskScore += 20;
factors.push('API_RATE_LIMIT_FREQUENTLY_HIT');
}
if (auditSummary.sensitiveActionCount > 10) {
riskScore += 15;
factors.push('ABNORMAL_SENSITIVE_ACTIONS');
}
riskScore = Math.min(riskScore, 100);
// 3. 确定威胁等级
let threatLevel: SecurityProfile['threatLevel'] = 'LOW';
if (riskScore > 75) threatLevel = 'CRITICAL';
else if (riskScore > 50) threatLevel = 'HIGH';
else if (riskScore > 25) threatLevel = 'MEDIUM';
const profile: SecurityProfile = {
tenantId,
riskScore,
threatLevel,
anomaliesDetected: factors.length,
lastAuditAt: new Date(),
topRiskFactors: factors
};
// 4. 保存/更新画像
await db(this.PROFILES_TABLE)
.insert({
tenantId,
riskScore,
threatLevel,
anomaliesDetected: factors.length,
lastAuditAt: new Date(),
topRiskFactors: JSON.stringify(factors),
created_at: new Date(),
updated_at: new Date()
})
.onConflict(['tenantId'])
.merge();
return profile;
} catch (err: any) {
logger.error(`[SecurityProfiling] Failed for tenant ${tenantId}: ${err.message}`);
throw err;
}
}
/**
* 获取租户风险画像
*/
static async getProfile(tenantId: string): Promise<SecurityProfile | null> {
return db(this.PROFILES_TABLE).where({ tenantId }).first();
}
}

View File

@@ -0,0 +1,98 @@
import { logger } from '../../utils/logger';
import { SemanticLogService } from '../telemetry/SemanticLogService';
import fs from 'fs';
import path from 'path';
/**
* [BIZ_KER_114] 自动化 SQL 注入防御扫描 (SQL Injection)
* @description 核心逻辑:静态分析代码中的 SQL 拼接风险。
* 扫描指定目录下的 .ts 文件,识别非参数化的 SQL 查询。
* 联动语义日志中心生成安全扫描报告。
*/
export class SecurityScanService {
private static readonly SCAN_TARGETS = [
path.join(__dirname, '../../domains'),
path.join(__dirname, '../../api/controllers')
];
/**
* 初始化扫描任务
*/
static async init() {
this.runScan();
setInterval(() => this.runScan(), 24 * 60 * 60 * 1000); // 每日扫描
logger.info(`[SecurityScan] SQL Injection defense scanner initialized`);
}
/**
* 执行静态代码扫描
*/
private static async runScan() {
try {
const report = await this.scanFiles();
await SemanticLogService.logSemantic(report, 'INFO', 'SECURITY_SCAN');
logger.info(`[SecurityScan] Daily scan report generated`);
} catch (err: any) {
logger.error(`[SecurityScan] Scan failed: ${err.message}`);
}
}
/**
* 递归扫描文件并分析内容
*/
private static async scanFiles(): Promise<string> {
let report = `### 🛡️ SQL Injection Security Audit (Static Analysis)\n\n`;
let vulnerabilities: string[] = [];
const walk = (dir: string) => {
const files = fs.readdirSync(dir);
for (const file of files) {
const fullPath = path.join(dir, file);
const stats = fs.statSync(fullPath);
if (stats.isDirectory()) {
walk(fullPath);
} else if (file.endsWith('.ts')) {
const content = fs.readFileSync(fullPath, 'utf8');
const vulns = this.analyzeContent(content, file);
vulnerabilities.push(...vulns);
}
}
};
this.SCAN_TARGETS.forEach(target => {
if (fs.existsSync(target)) walk(target);
});
if (vulnerabilities.length > 0) {
report += `**🚨 Found ${vulnerabilities.length} Potential SQL Injection Risks:**\n`;
vulnerabilities.forEach(v => report += `- ${v}\n`);
report += `\n**Optimization Advice:** 请始终使用 Knex 参数化查询 (\`where({ id: val })\`\`raw('?...', [val])\`),严禁使用模板字符串直接拼接 SQL 变量。\n`;
} else {
report += `**✅ No raw SQL string interpolation detected in monitored files.**\n`;
}
return report;
}
/**
* 分析文件内容中的 SQL 拼接模式
*/
private static analyzeContent(content: string, filename: string): string[] {
const risks: string[] = [];
// 识别常见危险模式raw(`...${var}...`) 或 query(`...${var}...`)
const rawPattern = /db\.raw\(`.*?\$\{.*?\}.*?`\)/g;
const knexPattern = /db\(.*?\)\.whereRaw\(`.*?\$\{.*?\}.*?`\)/g;
const rawMatches = content.match(rawPattern);
const knexMatches = content.match(knexPattern);
if (rawMatches) {
rawMatches.forEach(m => risks.push(`[${filename}] Potential raw SQL interpolation: \`${m.substring(0, 50)}...\``));
}
if (knexMatches) {
knexMatches.forEach(m => risks.push(`[${filename}] Potential whereRaw interpolation: \`${m.substring(0, 50)}...\``));
}
return risks;
}
}

View File

@@ -0,0 +1,78 @@
import { logger } from '../../utils/logger';
import db from '../../config/database';
export interface AuditProof {
id: string;
decisionId: string;
tenantId: string;
proofType: 'ZKP' | 'TEE_MEASUREMENT';
evidenceHash: string;
status: 'VERIFIED' | 'FAILED' | 'PENDING';
}
/**
* [CORE_SEC_25] 主权级决策审计存证链 (Sovereign Audit Trail)
* @description 核心逻辑:利用 ZKP 与 TEE (机密计算) 为 AGI 的每一个关键贸易决策(如:调价、采购、终止合作)提供不可篡改且保护隐私的存证审计链。
* 系统不仅存证“决策结果”,更通过“零知识哈希”存证“决策链路”,
* 允许监管机构在不看到业务明文的前提下,验证决策是否由受信任的 AGI 逻辑执行。
*/
export class SovereignAuditTrailService {
private static readonly AUDIT_TRAIL_TABLE = 'cf_sovereign_audit_trails';
/**
* 初始化表结构
*/
static async initTable() {
const hasTable = await db.schema.hasTable(this.AUDIT_TRAIL_TABLE);
if (!hasTable) {
console.log(`📦 Creating ${this.AUDIT_TRAIL_TABLE} table...`);
await db.schema.createTable(this.AUDIT_TRAIL_TABLE, (table) => {
table.string('audit_id', 64).primary();
table.string('decision_id', 64).notNullable();
table.string('tenant_id', 64).notNullable();
table.string('proof_type', 32).notNullable();
table.string('evidence_hash', 128).notNullable();
table.string('status', 16).defaultTo('PENDING');
table.json('audit_metadata');
table.timestamp('created_at').defaultTo(db.fn.now());
table.index(['tenant_id', 'decision_id', 'status']);
});
console.log(`✅ Table ${this.AUDIT_TRAIL_TABLE} created`);
}
}
/**
* 记录 AGI 决策审计证明
*/
static async logDecisionProof(tenantId: string, decisionId: string, evidence: any): Promise<string> {
const auditId = `AUDIT_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`;
logger.info(`[SovereignAudit] Logging decision proof for ${decisionId} (Tenant: ${tenantId})`);
// 1. 模拟生成证据哈希 (利用 SHA-256 对敏感决策数据进行脱敏哈希)
const evidenceHash = `sha256_${decisionId}_${Math.random().toString(36).substr(2, 10)}`;
await db(this.AUDIT_TRAIL_TABLE).insert({
audit_id: auditId,
decision_id: decisionId,
tenant_id: tenantId,
proof_type: 'ZKP',
evidence_hash: evidenceHash,
status: 'VERIFIED',
audit_metadata: JSON.stringify({ algorithm: 'SHA-256', env: 'TEE-Enclave' })
});
return auditId;
}
/**
* 验证决策的真实性与合规性 (Verification)
*/
static async verifyDecision(auditId: string): Promise<boolean> {
const proof = await db(this.AUDIT_TRAIL_TABLE).where({ audit_id: auditId }).first();
if (!proof) return false;
logger.info(`[SovereignAudit] Verifying decision proof ${auditId}`);
// 模拟 TEE 验证逻辑
return proof.status === 'VERIFIED';
}
}

View File

@@ -0,0 +1,96 @@
import { logger } from '../../utils/logger';
import { FeatureGovernanceService } from '../governance/FeatureGovernanceService';
import db from '../../config/database';
export interface QualificationProof {
tenantId: string;
requirementId: string; // e.g., 'VAT_REGISTERED', 'MIN_TURNOVER_100K'
proofHash: string; // The ZKP proof hash
isVerified: boolean;
verifiedAt: Date;
}
/**
* [CORE_SEC_08] 基于零知识证明 (ZKP) 的租户资质隐私验证 (ZKP Qualification)
* @description 允许租户在不泄露具体业务数据(如具体流水额)的情况下,证明其满足平台准入资质。
*/
export class ZKPQualificationService {
private static readonly PROOF_TABLE = 'cf_zkp_proofs';
/**
* 初始化数据库表
*/
static async initTable() {
const hasTable = await db.schema.hasTable(this.PROOF_TABLE);
if (!hasTable) {
logger.info(`📦 Creating ${this.PROOF_TABLE} table...`);
await db.schema.createTable(this.PROOF_TABLE, (table) => {
table.increments('id').primary();
table.string('tenant_id', 64).notNullable();
table.string('requirement_id', 100).notNullable();
table.string('proof_hash', 255).notNullable();
table.boolean('is_verified').defaultTo(false);
table.dateTime('verified_at');
table.timestamps(true, true);
table.unique(['tenant_id', 'requirement_id']);
});
}
}
/**
* 提交 ZKP 证明
* @description 租户端生成证明后提交 Hash服务端验证 Hash 是否符合预设 Circuit
*/
static async submitProof(tenantId: string, requirementId: string, proofHash: string): Promise<boolean> {
// [BIZ_GOV_06] 功能开关校验
if (!(await FeatureGovernanceService.isEnabled('CORE_SEC_ZKP', tenantId))) {
logger.info(`[ZKP] Service is disabled for Tenant ${tenantId}`);
return false;
}
logger.info(`[ZKP] Tenant ${tenantId} submitted proof for ${requirementId}`);
// 1. 验证证明 (此处为模拟 ZKP 验证逻辑)
// 实际场景下会调用 snarkjs 或类似的库验证 proofHash 是否符合 Circuit
const isValid = await this.verifyZKP(proofHash, requirementId);
if (isValid) {
await db(this.PROOF_TABLE)
.insert({
tenant_id: tenantId,
requirement_id: requirementId,
proof_hash: proofHash,
is_verified: true,
verified_at: new Date(),
created_at: new Date(),
updated_at: new Date()
})
.onConflict(['tenant_id', 'requirement_id'])
.merge();
logger.info(`[ZKP] Proof verified for ${tenantId} - ${requirementId}`);
return true;
}
return false;
}
/**
* 模拟 ZKP 验证过程
*/
private static async verifyZKP(proofHash: string, requirementId: string): Promise<boolean> {
// 模拟:只要不是 'invalid' 就认为通过
return proofHash !== 'invalid_proof';
}
/**
* 检查租户是否满足特定资质
*/
static async checkQualification(tenantId: string, requirementId: string): Promise<boolean> {
const proof = await db(this.PROOF_TABLE)
.where({ tenant_id: tenantId, requirement_id: requirementId, is_verified: true })
.first();
return !!proof;
}
}

View File

@@ -0,0 +1,165 @@
import { logger } from '../../../utils/logger';
import { AuditService } from '../../../services/AuditService';
import db from '../../../config/database';
export enum ApprovalStatus {
PENDING = 'PENDING',
APPROVED = 'APPROVED',
REJECTED = 'REJECTED',
EXPIRED = 'EXPIRED'
}
export interface ApprovalRequest {
id: string;
tenantId: string;
requesterId: string;
type: 'CREDENTIAL_RESET' | 'CREDENTIAL_EXPORT' | 'SYSTEM_CONFIG_CHANGE' | 'HIGH_VALUE_ORDER' | 'PRICE_CHANGE' | 'REFUND';
resourceId: string;
metadata: any;
status: ApprovalStatus;
currentStage: number;
totalStages: number;
approverId?: string;
reason?: string;
createdAt: Date;
expiresAt: Date;
}
/**
* [CORE_SEC_02] 授权审批服务 (Approval Service)
* [ERP_APPROVE_01] 通用审批流引擎 (Approval Engine)
* @description 管理高风险操作的多级审批流与规则引擎
*/
export class ApprovalService {
private static readonly TABLE_NAME = 'cf_approval_requests';
/**
* [ERP_APPROVE_01] 发起多级审批请求
*/
static async requestApproval(params: Omit<ApprovalRequest, 'id' | 'status' | 'createdAt' | 'expiresAt' | 'currentStage' | 'totalStages'>): Promise<string> {
const id = `APPV-${Date.now()}`;
// 规则引擎:根据类型与金额设定审批层级
let totalStages = 1;
const metadata = params.metadata || {};
if (params.type === 'HIGH_VALUE_ORDER' || (metadata.amount && metadata.amount > 5000)) {
totalStages = 2; // 大额订单需两级审批 (MANAGER -> FINANCE)
}
const request: ApprovalRequest = {
...params,
id,
status: ApprovalStatus.PENDING,
currentStage: 1,
totalStages,
createdAt: new Date(),
expiresAt: new Date(Date.now() + 48 * 3600 * 1000) // 48小时有效
};
logger.info(`[Approval] New ${totalStages}-stage request ${id} for ${params.type}`);
await db(this.TABLE_NAME).insert({
id: request.id,
tenant_id: request.tenantId,
requester_id: request.requesterId,
type: request.type,
resource_id: request.resourceId,
metadata: JSON.stringify(request.metadata),
status: request.status,
current_stage: request.currentStage,
total_stages: request.totalStages,
created_at: request.createdAt,
expires_at: request.expiresAt
});
return id;
}
/**
* [ERP_APPROVE_01] 执行审批 (支持多级流转)
*/
static async approve(requestId: string, approverId: string, decision: 'APPROVE' | 'REJECT', reason?: string): Promise<void> {
logger.info(`[Approval] Deciding request ${requestId}: ${decision} by ${approverId}`);
const request = await db(this.TABLE_NAME).where({ id: requestId }).first();
if (!request) throw new Error('Approval request not found');
if (decision === 'REJECT') {
await db(this.TABLE_NAME).where({ id: requestId }).update({
status: ApprovalStatus.REJECTED,
approver_id: approverId,
reason,
updated_at: new Date()
});
return;
}
// 如果是批准,检查是否需要进入下一级
if (request.current_stage < request.total_stages) {
await db(this.TABLE_NAME).where({ id: requestId }).update({
current_stage: request.current_stage + 1,
approver_id: approverId, // 记录当前审批人
updated_at: new Date()
});
logger.info(`[Approval] Request ${requestId} moved to stage ${request.current_stage + 1}`);
} else {
await db(this.TABLE_NAME).where({ id: requestId }).update({
status: ApprovalStatus.APPROVED,
approver_id: approverId,
reason,
updated_at: new Date()
});
}
// 记录审计日志
await AuditService.log({
tenantId: request.tenant_id,
traceId: `APPV-${Date.now()}`,
userId: approverId,
module: 'SECURITY',
action: decision,
resourceType: 'approval_request',
resourceId: requestId,
result: 'success',
metadata: { reason, stage: request.current_stage },
source: 'console'
});
}
/**
* 初始化表
*/
static async initTable() {
const exists = await db.schema.hasTable(this.TABLE_NAME);
if (!exists) {
logger.info(`📦 Creating ${this.TABLE_NAME} table...`);
await db.schema.createTable(this.TABLE_NAME, (table) => {
table.string('id', 64).primary();
table.string('tenant_id', 64).notNullable();
table.string('requester_id', 64).notNullable();
table.string('type', 64).notNullable();
table.string('resource_id', 64).notNullable();
table.json('metadata');
table.string('status', 16).defaultTo('PENDING');
table.integer('current_stage').defaultTo(1);
table.integer('total_stages').defaultTo(1);
table.string('approver_id', 64);
table.string('reason', 255);
table.timestamp('expires_at');
table.timestamps(true, true);
table.index(['tenant_id', 'status']);
});
logger.info(`✅ Table ${this.TABLE_NAME} created`);
} else {
// 增量字段校验
const hasCurrentStage = await db.schema.hasColumn(this.TABLE_NAME, 'current_stage');
if (!hasCurrentStage) {
await db.schema.alterTable(this.TABLE_NAME, (table) => {
table.integer('current_stage').defaultTo(1).after('status');
table.integer('total_stages').defaultTo(1).after('current_stage');
});
}
}
}
}

View File

@@ -0,0 +1,56 @@
import { logger } from '../../../utils/logger';
import { VaultService } from '../../../services/VaultService';
import { ApprovalService } from './ApprovalService';
import db from '../../../config/database';
/**
* [CORE_SEC_02] 凭据轮换服务 (Credential Rotation)
* @description 管理凭据的到期提醒、强制轮换与安全变更
*/
export class CredentialRotationService {
private static readonly ROTATION_INTERVAL_DAYS = 90;
/**
* 检查到期凭据
*/
static async checkExpiringCredentials(): Promise<any[]> {
const thresholdDate = new Date();
thresholdDate.setDate(thresholdDate.getDate() - this.ROTATION_INTERVAL_DAYS);
const expiring = await db('cf_credential_vault')
.where('updated_at', '<', thresholdDate)
.orWhereNotNull('expires_at')
.andWhere('expires_at', '<', new Date());
return expiring;
}
/**
* 发起受控轮换 (需审批)
*/
static async initiateControlledRotation(tenantId: string, credentialId: number, userId: string): Promise<string> {
logger.info(`[Rotation] Initiating controlled rotation for ${credentialId} by user ${userId}`);
const approvalId = await ApprovalService.requestApproval({
tenantId,
requesterId: userId,
type: 'CREDENTIAL_RESET',
resourceId: String(credentialId),
metadata: { action: 'ROTATE', strategy: 'FORCE_NEXT_LOGIN' }
});
return approvalId;
}
/**
* 执行轮换逻辑
*/
static async performRotation(
context: { tenantId: string; userId: string; traceId: string },
credentialId: number,
newPassword: string
): Promise<void> {
logger.info(`[Rotation] Executing rotation for ${credentialId}`);
await VaultService.rotateCredential(context, credentialId, newPassword);
}
}

View File

@@ -0,0 +1,73 @@
import * as crypto from 'crypto';
import { logger } from '../../utils/logger';
/**
* [CORE_SEC_07] 全链路 mTLS 强制加密引擎
* @description 模拟分布式节点间的双向 TLS 握手与证书校验,确保内部通信绝对安全
*/
export class mTLSEngine {
private static CA_CERT = '---BEGIN CERTIFICATE--- CRAWLFUL_ROOT_CA ---END CERTIFICATE---';
/**
* 生成临时节点证书 (模拟)
*/
static generateNodeCert(nodeId: string) {
return {
nodeId,
cert: `---BEGIN CERTIFICATE--- ${nodeId}_CERT ---END CERTIFICATE---`,
issuedAt: Date.now(),
expiresAt: Date.now() + 365 * 24 * 60 * 60 * 1000,
fingerprint: crypto.createHash('sha256').update(nodeId).digest('hex')
};
}
/**
* 校验对端证书
*/
static verifyPeerCert(cert: any): boolean {
if (!cert || !cert.fingerprint) {
logger.error('[mTLS] Missing peer certificate');
return false;
}
// 1. 模拟 CA 签名校验
const isValidSignature = cert.cert.includes('---BEGIN CERTIFICATE---');
if (!isValidSignature) {
logger.error(`[mTLS] Invalid certificate signature from node ${cert.nodeId}`);
return false;
}
// 2. 模拟指纹校验
const expectedFingerprint = crypto.createHash('sha256').update(cert.nodeId).digest('hex');
if (cert.fingerprint !== expectedFingerprint) {
logger.error(`[mTLS] Fingerprint mismatch for node ${cert.nodeId}`);
return false;
}
// 3. 校验过期时间
if (Date.now() > cert.expiresAt) {
logger.error(`[mTLS] Certificate expired for node ${cert.nodeId}`);
return false;
}
logger.debug(`[mTLS] Successfully verified node ${cert.nodeId}`);
return true;
}
/**
* 强制执行 mTLS 校验的装饰器 (模拟)
*/
static secureCall(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
const context = args[0]; // 假设第一个参数包含安全上下文
if (!mTLSEngine.verifyPeerCert(context?.peerCert)) {
throw new Error(`[mTLS] Forbidden: Secure call to ${propertyKey} failed verification`);
}
return originalMethod.apply(this, args);
};
return descriptor;
}
}