代码签名
代码签名是一种安全技术,用于证明某个应用是由您创建的。 您应该对应用程序进行签名,以免触发任何操作系统安全警告。

Windows 和 macOS 都会阻止用户运行未签名的应用程序。 在不进行代码签名的情况下分发应用程序是可行的——但为了运行它们,用户需要执行多个高级且需要手动操作的步骤。
如果您正在构建一个打算打包和分发的 Electron 应用,则应该对其进行代码签名。Electron 生态系统工具使对应用进行代码签名变得简单——本文档说明如何在 Windows 和 macOS 上对应用进行签名。
签名和公证 macOS 构建¶
为发布准备 macOS 应用程序需要两个步骤:首先, 需要对应用进行代码签名。然后,需要将应用上传到 Apple,进行一个称为公证的过程,自动化系统会进一步验证 您的应用没有做任何危害用户的事情。
开始此流程之前,请确保您满足对应用进行签名和 公证的要求:
- 加入 Apple Developer Program(需要缴纳年费)
- 下载并安装 Xcode——这需要一台运行 macOS 的计算机
- 生成、下载并安装 signing certificates
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][] 了解许多可能的配置选项。
```js @ts-nocheck 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 应用 {#signing-mac-app-store-applications}
参见 [Mac App Store Guide][]。
## 需要代码签名的 macOS API {#macos-apis-that-require-code-signing}
Electron 暴露的许多 macOS API 依赖于系统框架(例如 Keychain
Access 和 `Squirrel.Mac`),这些框架只有在您的应用经过代码签名后才能正常工作。
在测试这些 API 时,请记住,未签名或临时签名的应用可能会出现
不一致的行为,而看似 Electron 缺陷的问题通常可以通过正确
签名(并公证)您的应用来解决:
- [`safeStorage`](../api/safe-storage.md) - 如果没有有效且一致的代码签名,
macOS 可能无法识别您的未签名应用的两个构建是“同一个应用”,
这可能导致 Keychain 在每次更新后再次提示用户授予权限。
- [`app.setLoginItemSettings()`](../api/app.md#appsetloginitemsettingssettings-macos-windows) -
当应用未打包、未代码签名且未公证时,登录项可能会表现不正确(例如静默注册失败)。
- [`cookieEncryption` fuse](fuses.md#cookieencryption) - Cookie 加密使用
与 `safeStorage` 相同的操作系统级 Keychain 访问方式,因此具有相同的代码
签名要求。
- [`autoUpdater`](../api/auto-updater.md) - `Squirrel.Mac` 要求应用必须
经过签名,自动更新才能工作。
## 签名 Windows 构建 {#signing-windows-builds}
### 使用 Azure Artifact Signing {#using-azure-artifact-signing}
[Azure Artifact Signing][](以前称为 Azure Trusted Signing)是 Microsoft 的现代基于云的签名服务。
它是 Windows 上代码签名的最便宜选项,并且可以消除 SmartScreen 警告。
Azure Artifact Signing 目前仅限于某些国家的开发者。请参阅
[Artifact Signing 文档](https://learn.microsoft.com/en-us/azure/artifact-signing/quickstart#prerequisites)
以查看 Artifact Signing 是否在您所在国家/地区可用。
#### 使用 `jsign` 进行 Azure Artifact Signing {#using-jsign-for-azure-artifact-signing}
对于 Linux 或 macOS 上的开发者,[`jsign`](https://ebourg.github.io/jsign/) 可用于通过 Azure Artifact Signing 对 Windows 应用进行签名。用法示例:
```bash
jsign --storetype TRUSTEDSIGNING \
--keystore https://eus.codesigning.azure.net/ \
--storepass $AZURE_ACCESS_TOKEN \
--alias trusted-sign-acct/AppName \
--tsaurl http://timestamp.acs.microsoft.com/ \
--tsmode RFC3161 \
--replace <file>
使用 Electron Forge¶
Electron Forge 是推荐的应用签名方式,也可用于对 Squirrel.Windows
和 WiX MSI 安装程序进行签名。Azure Artifact Signing 的说明可以在
此处找到。
使用 Electron Builder¶
有关 Azure Artifact Signing 的 Electron Builder 文档可以在 此处找到。
使用传统证书¶
在对应用程序进行代码签名之前,您需要获取一个代码签名 证书。与 Apple 不同,Microsoft 允许开发者在公开市场上购买这些 证书。它们通常也由提供 HTTPS 证书的同一些公司出售。价格各不相同,因此花些时间 货比三家可能值得。流行的经销商包括:
需要特别指出的是,自 2023 年 6 月起,Microsoft 要求软件必须使用“扩展验证”证书进行签名,也称为“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][] 了解许多可能的配置选项。
```js @ts-nocheck 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) {#using-electron-winstaller-squirrelwindows}
[`electron-winstaller`][] 是一个可以为你的 Electron 应用生成 Squirrel.Windows 安装程序的包。这是 Electron Forge 的 [Squirrel.Windows Maker][maker-squirrel] 在底层使用的工具。与 `@electron/packager` 一样,它在底层使用 [`@electron/windows-sign`][],并支持相同的 `windowsSign` 选项。
```js {10-11} @ts-nocheck
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 选项。
```js {12-13} @ts-nocheck 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 your binaries as part 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 指南][]。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 el/electron