下面我们将详细介绍如何将锐安信远程代码签名服务集成到Electron应用的构建流程中,实现使用 electron-builder 对 Windows 平台的安装包和可执行文件进行自动签名。
事前准备:
已拥有可用的锐安信远程代码签名服务账户,并获取了有效的访问凭证(AK/SK)。
已有一个用于签名的远程代码签名服务。
项目基于 electron-builder 进行构建。
集成步骤
步骤一:配置 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);
}
}
步骤二:编译
配置完成后,运行您的 Electron 构建命令。构建过程中会自动调用上述自定义签名函数。
示例:构建 Windows 64位 安装包
npm run compile -- --win --x64
或使用 npx
npx electron-builder build --config electron-builder.mjs --win --x64
编译过程

编译结果
安装包以及主程序都已签名
