본문으로 건너뛰기

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 통합