#!/usr/bin/env node import { chmodSync, existsSync, mkdirSync, writeFileSync } from "node:fs"; import { createHash, createPublicKey, generateKeyPairSync } from "node:crypto"; import { dirname, resolve } from "node:path"; import { parseArgs } from "node:util"; const { values } = parseArgs({ options: { "private-key": { type: "string", default: ".secrets/release-signing-private.pem" }, "public-key": { type: "string", default: "distribution/release-signing-public.pem" }, } }); const privatePath = resolve(String(values["private-key"])); const publicPath = resolve(String(values["public-key"])); if (existsSync(privatePath) || existsSync(publicPath)) throw new Error("发布签名密钥已存在;拒绝覆盖或静默轮换"); const pair = generateKeyPairSync("ed25519"); const privatePem = pair.privateKey.export({ type: "pkcs8", format: "pem" }); const publicPem = pair.publicKey.export({ type: "spki", format: "pem" }); mkdirSync(dirname(privatePath), { recursive: true, mode: 0o700 }); mkdirSync(dirname(publicPath), { recursive: true, mode: 0o755 }); writeFileSync(privatePath, privatePem, { mode: 0o600 }); writeFileSync(publicPath, publicPem, { mode: 0o644 }); if (process.platform !== "win32") chmodSync(privatePath, 0o600); const keyId = createHash("sha256").update(createPublicKey(publicPem).export({ type: "spki", format: "der" })).digest("hex"); console.log(`发布签名密钥已生成;keyId=${keyId}`); console.log(`私钥(禁止提交或部署到下载目录):${privatePath}`); console.log(`公钥(应提交 Git):${publicPath}`);