112 lines
4.3 KiB
TypeScript
112 lines
4.3 KiB
TypeScript
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,正式部署前请确认不是示例地址。');
|