import * as crypto from 'crypto'; import * as fs from 'fs'; import * as path from 'path'; // 生成 RSA 密钥对 const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 2048, publicKeyEncoding: { type: 'spki', format: 'pem', }, privateKeyEncoding: { type: 'pkcs8', format: 'pem', }, }); // 生成 AES 密钥(32字节) const aesKey = crypto.randomBytes(32).toString('hex'); // 生成 JWT 密钥 const jwtSecret = crypto.randomBytes(32).toString('hex'); // 生成许可证请求签名密钥 const licenseRequestSigningSecret = crypto.randomBytes(32).toString('hex'); // 生成付费模块短期拉包 token 签名密钥 const modulePullTokenSecret = crypto.randomBytes(32).toString('hex'); // 主库加密密钥 const mainDbEncryptionKey = crypto.randomBytes(32).toString('hex'); // Docker Compose 默认数据库参数;裸机本地调试可用 LICENSE_DB_HOST=localhost 覆盖 const postgresUser = 'license'; const postgresPassword = crypto.randomBytes(18).toString('base64url'); const postgresDb = 'license_db'; const databaseHost = process.env.LICENSE_DB_HOST?.trim() || 'postgres'; const mainDatabaseUrl = `postgresql://${postgresUser}:${postgresPassword}@${databaseHost}:5432/${postgresDb}?schema=main`; const projectDatabaseUrl = `postgresql://${postgresUser}:${postgresPassword}@${databaseHost}:5432/${postgresDb}?schema=public`; const adminInitialPassword = crypto.randomBytes(18).toString('base64url'); const premiumModuleRegistryBase = process.env.PREMIUM_MODULE_REGISTRY_BASE?.trim() || 'registry.example.com/flnxi/premium'; const premiumModuleVersion = process.env.PREMIUM_MODULE_VERSION?.trim() || '1.0.0'; // 创建 keys 目录 const keysDir = path.join(__dirname, '..', 'keys'); if (!fs.existsSync(keysDir)) { fs.mkdirSync(keysDir, { recursive: true }); } // 保存密钥文件 fs.writeFileSync(path.join(keysDir, 'private.key'), privateKey); fs.writeFileSync(path.join(keysDir, 'public.key'), publicKey); // 生成 .env 内容 const envContent = `# 数据库连接 # Docker Compose 部署默认使用 postgres 作为数据库主机名。 # 裸机本地调试可先设置 LICENSE_DB_HOST=localhost 再运行 generate-keys。 POSTGRES_USER="${postgresUser}" POSTGRES_PASSWORD="${postgresPassword}" POSTGRES_DB="${postgresDb}" MAIN_DATABASE_URL="${mainDatabaseUrl}" MAIN_DB_ENCRYPTION_KEY="${mainDbEncryptionKey}" DATABASE_URL="${projectDatabaseUrl}" # RSA 私钥(用于签名许可证) RSA_PRIVATE_KEY="${privateKey.replace(/\n/g, '\\n')}" # RSA 公钥(嵌入客户端用于验证签名) RSA_PUBLIC_KEY="${publicKey.replace(/\n/g, '\\n')}" # AES 加密密钥 AES_SECRET_KEY="${aesKey}" # JWT 密钥 JWT_SECRET="${jwtSecret}" # 许可证请求签名密钥(素材系统需使用同一值) LICENSE_REQUEST_SIGNING_SECRET="${licenseRequestSigningSecret}" # 付费模块短期拉包 token 签名密钥 MODULE_PULL_TOKEN_SECRET="${modulePullTokenSecret}" # 授权模块分发:模块核心本体在镜像站,验证服务器只发授权清单和凭证 PREMIUM_MODULE_REGISTRY_BASE="${premiumModuleRegistryBase}" PREMIUM_MODULE_VERSION="${premiumModuleVersion}" # 管理员初始密码 ADMIN_INITIAL_PASSWORD="${adminInitialPassword}" `; fs.writeFileSync(path.join(__dirname, '..', '.env'), envContent); console.log('✅ 密钥生成完成!'); console.log(''); console.log('文件已生成:'); console.log(' - keys/private.key (RSA 私钥)'); console.log(' - keys/public.key (RSA 公钥)'); console.log(' - .env (环境变量配置)'); console.log(''); console.log('⚠️ 请妥善保管私钥,不要提交到代码仓库!'); console.log(''); console.log('📋 客户端公钥(复制到素材系统):'); console.log('─'.repeat(50)); console.log(publicKey); console.log(''); console.log('📋 许可证服务初始管理员密码已写入 license-server/.env 的 ADMIN_INITIAL_PASSWORD,不在终端日志中输出明文。'); console.log('📋 许可证请求签名密钥已写入 license-server/.env 的 LICENSE_REQUEST_SIGNING_SECRET,请在素材系统中配置同一值。'); console.log('📋 付费模块短期拉包 token 密钥已写入 license-server/.env 的 MODULE_PULL_TOKEN_SECRET,仅许可证服务使用。'); console.log('📋 授权模块镜像站已写入 license-server/.env 的 PREMIUM_MODULE_REGISTRY_BASE,正式部署前请确认不是示例地址。');