跳至主要内容

代码签名

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

macOS Sonoma Gatekeeper warning: The app is damaged

Windows 和 macOS 都阻止用户运行未签名的应用程序。可以分发未经代码签名的应用程序,但为了运行它们,用户需要执行多个高级手动步骤才能运行它们。

如果您正在构建打算打包和分发的 Electron 应用程序,则应该对其进行代码签名。Electron 生态系统工具使对应用程序进行代码签名变得简单明了 - 本文档解释了如何在 Windows 和 macOS 上对应用程序进行签名。

签名和公证 macOS 构建

准备用于发布的 macOS 应用程序需要两个步骤:首先,应用程序需要进行代码签名。然后,应用程序需要上传到 Apple,进行一个称为 **公证** 的过程,在这个过程中,自动系统将进一步验证您的应用程序是否不会对用户构成任何威胁。

要开始此过程,请确保您满足对应用程序进行签名和公证的要求。

  1. 注册加入 Apple Developer Program(需要支付年度费用)
  2. 下载并安装 Xcode - 这需要运行 macOS 的计算机
  3. 生成、下载并安装 签名证书

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: '[email protected]',
appleIdPassword: 'my-apple-id-password'
}
})

签名 Mac App Store 应用程序

请参阅 Mac App Store 指南

签名 Windows 构建

在对应用程序进行代码签名之前,您需要获取代码签名证书。与 Apple 不同,Microsoft 允许开发人员在公开市场上购买这些证书。它们通常由与提供 HTTPS 证书的同一家公司出售。价格各不相同,因此花时间货比三家可能会有所帮助。受欢迎的经销商包括

重要的是要注意,自 2023 年 6 月起,Microsoft 要求软件使用“扩展验证”证书(也称为“EV 代码签名证书”)进行签名。过去,开发人员可以使用更简单、更便宜的证书进行软件签名,例如“Authenticode 代码签名证书”或“基于软件的 OV 证书”。这些更简单的证书不再提供任何好处:Windows 会将您的应用程序视为完全未签名,并显示等效的警告对话框。

新的 EV 证书需要存储在符合 FIPS 140 2 级、通用标准 EAL 4+ 或等效标准的硬件存储模块中。换句话说,证书不能简单地下载到 CI 基础设施中。在实践中,这些存储模块看起来像高级的 USB 闪存驱动器。

许多证书提供商现在提供“基于云的签名” - 整个签名硬件都在他们的数据中心,您可以使用它来远程签名代码。这种方法在 Electron 维护人员中很受欢迎,因为它使在 CI(如 GitHub Actions、CircleCI 等)中签名应用程序变得相对容易。

在撰写本文时,Electron 自己的应用程序使用 DigiCert KeyLocker,但任何提供用于签名文件的命令行工具的提供商都与 Electron 的工具兼容。

Electron 生态系统中的所有工具都使用 @electron/windows-sign,并且通常通过 windowsSign 属性公开配置选项。您可以直接使用它来签名文件,也可以在 Electron Forge、@electron/packagerelectron-winstallerelectron-wix-msi 中使用相同的 windowsSign 配置。

使用 Electron Forge

Electron Forge 是签署您的应用程序以及 Squirrel.WindowsWiX 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 应用商店应用程序

查看 Windows 应用商店指南