代码签名
代码签名是一种安全技术,用于证明应用是由您创建的。您应该对应用进行签名,以免触发任何操作系统安全警告。
Windows 和 macOS 都阻止用户运行未签名的应用。分发未签名的应用是可能的,但用户需要经过多个高级且手动步骤才能运行它们。
如果您正在构建打算打包和分发的 Electron 应用,则应该对其进行代码签名。Electron 生态系统的工具使应用的代码签名变得简单直接 - 本文档解释了如何在 Windows 和 macOS 上对应用进行签名。
签署和公证 macOS 构建
准备发布 macOS 应用需要两个步骤:首先,应用需要进行代码签名。然后,应用需要上传到 Apple 进行一个称为**公证**的过程,自动化系统将进一步验证您的应用没有做任何危及用户的事情。
要开始此过程,请确保您满足应用签名和公证的要求
- 注册 Apple Developer Program(需要年费)
- 下载并安装 Xcode - 这需要一台运行 macOS 的电脑
- 生成、下载并安装签名证书
Electron 的生态系统倾向于配置的灵活性和自由度,因此有多种方法可以对您的应用进行签名和公证。
使用 Electron Forge
如果您正在使用 Electron 最受欢迎的构建工具,对应用进行签名和公证只需要在配置中添加几项内容。Forge 是官方 Electron 工具的集合,底层使用`@electron/packager`、`@electron/osx-sign` 和 `@electron/notarize`。
有关如何配置应用的详细说明,请参阅 Electron Forge 文档中的签名 macOS 应用指南。
使用 Electron Packager
如果您没有使用像 Forge 这样的集成构建流程,您很可能在使用`@electron/packager`,它包含`@electron/osx-sign` 和 `@electron/notarize`。
如果您正在使用 Packager 的 API,您可以传入同时签名和公证应用的配置。如果下面的示例不满足您的需求,请参阅`@electron/osx-sign` 和 `@electron/notarize` 了解许多可能的配置选项。
const packager = require('@electron/packager')
packager({
dir: '/path/to/my/app',
osxSign: {},
osxNotarize: {
appleId: 'felix@felix.fun',
appleIdPassword: 'my-apple-id-password'
}
})
签署 Mac App Store 应用
请参阅Mac App Store 指南。
签署 Windows 构建
在对应用进行代码签名之前,您需要获取代码签名证书。与 Apple 不同,微软允许开发者在公开市场上购买这些证书。它们通常由提供 HTTPS 证书的同一家公司出售。价格各不相同,因此花点时间比较一下是值得的。常见的经销商包括
- Certum EV 代码签名证书
- DigiCert EV 代码签名证书
- Entrust EV 代码签名证书
- GlobalSign EV 代码签名证书
- IdenTrust EV 代码签名证书
- Sectigo (原 Comodo) EV 代码签名证书
- SSL.com EV 代码签名证书
值得注意的是,自 2023 年 6 月起,微软要求软件必须使用“扩展验证”证书(也称为“EV 代码签名证书”)进行签名。过去,开发者可以使用一种更简单、更便宜的证书进行软件签名,称为“authenticode 代码签名证书”或“基于软件的 OV 证书”。这些更简单的证书不再提供任何好处:Windows 将把您的应用视为完全未签名,并显示相应的警告对话框。
新的 EV 证书必须存储在符合 FIPS 140 Level 2、Common Criteria EAL 4+ 或同等标准的硬件存储模块上。换句话说,证书不能简单地下载到 CI 基础设施上。实际上,这些存储模块看起来像高级的 USB 闪存盘。
许多证书提供商现在提供“基于云的签名”服务 - 整个签名硬件位于他们的数据中心,您可以使用它远程签署代码。这种方法在 Electron 维护者中很受欢迎,因为它使得在 CI(如 GitHub Actions、CircleCI 等)中签名应用相对容易。
在撰写本文时,Electron 自己的应用使用 DigiCert KeyLocker,但任何提供用于签署文件的命令行工具的提供商都将与 Electron 的工具兼容。
Electron 生态系统中的所有工具都使用 `@electron/windows-sign`,通常通过 `windowsSign` 属性暴露配置选项。您可以直接使用它来签署文件,或者在 Electron Forge、`@electron/packager`、`electron-winstaller` 和 `electron-wix-msi` 中使用相同的 `windowsSign` 配置。
使用 Electron Forge
Electron Forge 是签署您的应用以及 `Squirrel.Windows` 和 `WiX MSI` 安装程序的推荐方式。有关如何配置应用的详细说明,请参阅Electron Forge 代码签名教程。
使用 Electron Packager
如果您没有使用像 Forge 这样的集成构建流程,您很可能在使用`@electron/packager`,它包含`@electron/windows-sign`。
如果您正在使用 Packager 的 API,您可以传入用于签名应用的配置。如果下面的示例不满足您的需求,请参阅`@electron/windows-sign` 了解许多可能的配置选项。
const packager = require('@electron/packager')
packager({
dir: '/path/to/my/app',
windowsSign: {
signWithParams: '--my=custom --parameters',
// If signtool.exe does not work for you, customize!
signToolPath: 'C:\\Path\\To\\my-custom-tool.exe'
}
})
使用 electron-winstaller (Squirrel.Windows)
`electron-winstaller` 是一个可以为您的 Electron 应用生成 Squirrel.Windows 安装程序的包。这是 Electron Forge 的 Squirrel.Windows Maker 在底层使用的工具。就像 `@electron/packager` 一样,它在底层使用 `@electron/windows-sign`,并支持相同的 `windowsSign` 选项。
const electronInstaller = require('electron-winstaller')
// NB: Use this syntax within an async function, Node does not have support for
// top-level await as of Node 12.
try {
await electronInstaller.createWindowsInstaller({
appDirectory: '/tmp/build/my-app-64',
outputDirectory: '/tmp/build/installer64',
authors: 'My App Inc.',
exe: 'myapp.exe',
windowsSign: {
signWithParams: '--my=custom --parameters',
// If signtool.exe does not work for you, customize!
signToolPath: 'C:\\Path\\To\\my-custom-tool.exe'
}
})
console.log('It worked!')
} catch (e) {
console.log(`No dice: ${e.message}`)
}
有关完整的配置选项,请查阅`electron-winstaller` 仓库!
使用 electron-wix-msi (WiX MSI)
`electron-wix-msi` 是一个可以为您的 Electron 应用生成 MSI 安装程序的包。这是 Electron Forge 的 MSI Maker 在底层使用的工具。就像 `@electron/packager` 一样,它在底层使用 `@electron/windows-sign`,并支持相同的 `windowsSign` 选项。
import { MSICreator } from 'electron-wix-msi'
// Step 1: Instantiate the MSICreator
const msiCreator = new MSICreator({
appDirectory: '/path/to/built/app',
description: 'My amazing Kitten simulator',
exe: 'kittens',
name: 'Kittens',
manufacturer: 'Kitten Technologies',
version: '1.1.2',
outputDirectory: '/path/to/output/folder',
windowsSign: {
signWithParams: '--my=custom --parameters',
// If signtool.exe does not work for you, customize!
signToolPath: 'C:\\Path\\To\\my-custom-tool.exe'
}
})
// Step 2: Create a .wxs template file
const supportBinaries = await msiCreator.create()
// 🆕 Step 2a: optionally sign support binaries if you
// sign you binaries as part of of your packaging script
for (const binary of supportBinaries) {
// Binaries are the new stub executable and optionally
// the Squirrel auto updater.
await signFile(binary)
}
// Step 3: Compile the template to a .msi file
await msiCreator.compile()
有关完整的配置选项,请查阅`electron-wix-msi` 仓库!
使用 Electron Builder
Electron Builder 提供了一个自定义的应用签名解决方案。您可以在此处找到其文档。
签署 Windows Store 应用
请参阅Windows Store 指南。