メインコンテンツまでスキップ

Electron Builderとの統合

本ドキュメントでは、リモートコード署名サービスをElectronアプリのビルドフローに統合し、electron-builder を使用してWindowsプラットフォームのインストーラーと実行ファイルに自動署名する方法について説明します。

ヒント

ここではオープンソースプロジェクト vite-electron-builder を使用してテストを行います。

前提条件

  1. 利用可能なsslTrusリモートコード署名サービスアカウントを保有し、有効なアクセスクレデンシャル(AK/SK)を取得していること。
  2. 署名に使用するリモートコード署名サービスを用意していること。
  3. プロジェクトが electron-builder でビルドされていること。

統合手順

手順1:Electron Builder設定ファイルを構成する

Electron プロジェクトのルートディレクトリで、electron-builder.mjs(または electron-builder.yml/config.js)ファイルを見つけて修正します。

以下は完全な設定例です。デフォルト設定を修正し、signtoolOptions.sign のカスタム署名メソッドを追加する必要があります。

export default /** @type import('electron-builder').Configuration */
({
win: {
target: [
{
target: 'nsis',
arch: ['x64'],
},
],
signtoolOptions: {
sign: customSign,
signingHashAlgorithms: ['sha256'], // 这里只需要选择一个即可,实际的双签由 customSign 执行
},
},
});

async function customSign(configuration) {
const srcPath = configuration.path;
const cwd = process.cwd();
const relPath = relative(cwd, srcPath);

// 设置环境变量 export SIGNTOOL_ACCESS_KEY='' SIGNTOOL_ACCESS_SECRET='' SIGNTOOL_CERT_CODE=''
const {SIGNTOOL_ACCESS_KEY, SIGNTOOL_ACCESS_SECRET, SIGNTOOL_CERT_CODE} = process.env;
if (!SIGNTOOL_ACCESS_KEY || !SIGNTOOL_ACCESS_SECRET || !SIGNTOOL_CERT_CODE) {
console.error(`[ERROR] Missing environment variables: SIGNTOOL_ACCESS_KEY, SIGNTOOL_ACCESS_SECRET, SIGNTOOL_CERT_CODE`);
return;
}

// 下载对应平台的命令行工具
const signtoolPath = join(cwd, 'signtool', 'signtool');
const dir = dirname(srcPath);
const ext = extname(srcPath);
const name = basename(srcPath, ext);
const randomStr = randomBytes(4).toString('hex');
const tempPath = join(dir, `${name}-${randomStr}${ext}`);

const startTime = Date.now();

try {
console.log(`[SIGNING] ${relPath}`);

const logFilePath = join(cwd, 'signtool', name + '.log');
writeFileSync(logFilePath, `Source: ${srcPath}\nTime: ${new Date().toLocaleString()}\n\n`);
const logFd = openSync(logFilePath, 'a');

// 签名默认不会覆盖源文件,且目标文件不存在,所以先将源文件重命名为临时文件
renameSync(srcPath, tempPath);

// 参数可参考 signtool 命令行解析
const command = [
signtoolPath,
'sign',
`-k "${SIGNTOOL_ACCESS_KEY}"`,
`-s "${SIGNTOOL_ACCESS_SECRET}"`,
`-c "${SIGNTOOL_CERT_CODE}"`,
`-f "${tempPath}"`, // 源文件
`-o "${srcPath}"`, // 目标文件
'--nest=true', // 嵌套签名
'--sha1=false', // sha1 签名,对于 bool 值的参数传递需要使用 arg=value 的方式,不可使用 arg value 的形式
'--timestamp http://timestamp.sectigo.com',
'--sha2=true', // sha2 签名
'--timestamp-rfc3161 http://timestamp.sectigo.com',
].join(' ');

// 将 signtool 的日志输出到文件
execSync(command, {stdio: ['ignore', logFd, logFd]});

// 删除临时文件
rmSync(tempPath, {force: true});

const duration = ((Date.now() - startTime) / 1000).toFixed(2);
console.log(`[SUCCESS] Finished in ${duration}s -> ${relPath}`);
} catch (e) {
console.error(`[FAILURE] Failed to sign: ${relPath}`);
console.error(` Check log: signtool/${name}.log`);
process.exit(1);
}
}

ステップ2:コンパイル

設定が完了したら、Electronのビルドコマンドを実行してください。ビルドプロセス中に、上記のカスタム署名関数が自動的に呼び出されます。

# 示例:构建 Windows 64位 安装包
npm run compile -- --win --x64
# 或使用 npx
npx electron-builder build --config electron-builder.mjs --win --x64

コンパイルプロセス

リモートコード署名サービスと Electron Builder の統合

コンパイル結果

インストールパッケージとメインプログラムの両方が署名済みです

リモートコード署名サービスと Electron Builder の統合

リモートコード署名サービスと Electron Builder の統合