Skip to main content

Code Signing代码签名

Code signing is a security technology that you use to certify that an app was created by you. 代码签名是一种安全技术,用于证明应用程序是由您创建的。You should sign your application so it does not trigger any operating system security checks.您应该对应用程序进行签名,这样它就不会触发任何操作系统安全检查。

On macOS, the system can detect any change to the app, whether the change is introduced accidentally or by malicious code.在macOS上,系统可以检测到应用程序的任何更改,无论更改是意外引入的还是恶意代码引入的。

On Windows, the system assigns a trust level to your code signing certificate which if you don't have, or if your trust level is low, will cause security dialogs to appear when users start using your application. 在Windows上,系统会为您的代码签名证书分配一个信任级别,如果您没有,或者您的信任级别很低,那么当用户开始使用您的应用程序时,会出现安全对话框。Trust level builds over time so it's better to start code signing as early as possible.信任级别会随着时间而建立,因此最好尽早开始代码签名。

While it is possible to distribute unsigned apps, it is not recommended. 虽然可以分发未签名的应用程序,但不建议这样做。Both Windows and macOS will, by default, prevent either the download or the execution of unsigned applications. 默认情况下,Windows和macOS都会阻止未签名应用程序的下载或执行。Starting with macOS Catalina (version 10.15), users have to go through multiple manual steps to open unsigned applications.从macOS Catalina(10.15版)开始,用户必须通过多个手动步骤才能打开未签名的应用程序。

macOS Catalina Gatekeeper warning: The app cannot be opened because the developer cannot be verified

As you can see, users get two options: Move the app straight to the trash or cancel running it. 正如你所看到的,用户有两种选择:直接将应用程序移到垃圾箱或取消运行。You don't want your users to see that dialog.您不希望用户看到该对话框。

If you are building an Electron app that you intend to package and distribute, it should be code signed.如果您正在构建一个打算打包和分发的Electron应用程序,它应该经过代码签名。

Signing & notarizing macOS builds签署和公证macOS版本

Properly preparing macOS applications for release requires two steps. 正确准备要发布的macOS应用程序需要两个步骤。First, the app needs to be code signed. 首先,应用程序需要代码签名。Then, the app needs to be uploaded to Apple for a process called notarization, where automated systems will further verify that your app isn't doing anything to endanger its users.然后,应用程序需要上传到苹果进行一个称为公证的过程,自动系统将进一步验证你的应用程序没有做任何危害用户的事情。

To start the process, ensure that you fulfill the requirements for signing and notarizing your app:要启动该流程,请确保您满足签署和公证应用程序的要求:

  1. Enroll in the Apple Developer Program (requires an annual fee)注册Apple Developer Program(需要年费)
  2. Download and install Xcode - this requires a computer running macOS下载并安装Xcode-这需要运行macOS的计算机
  3. Generate, download, and install signing certificates生成、下载和安装签名证书

Electron's ecosystem favors configuration and freedom, so there are multiple ways to get your application signed and notarized.Electron的生态系统支持配置和自由,因此有多种方法可以让您的申请得到签名和公证。

Using Electron Forge使用Electron锻造

If you're using Electron's favorite build tool, getting your application signed and notarized requires a few additions to your configuration. 如果您正在使用Electron最喜欢的构建工具,那么要使您的应用程序得到签名和公证,需要对您的配置进行一些补充。Forge is a collection of the official Electron tools, using electron-packager, electron-osx-sign, and electron-notarize under the hood.Forge是一个官方Electron工具的集合,使用Electron包装器electron-osx-signelectron-notarize

Let's take a look at an example package.json configuration with all required fields. 让我们看一个包含所有必填字段的package.json配置示例。Not all of them are required: the tools will be clever enough to automatically find a suitable identity, for instance, but we recommend that you are explicit.并非所有这些都是必需的:例如,这些工具足够聪明,可以自动找到合适的身份,但我们建议您明确。

package.json
{
"name": "my-app",
"version": "0.0.1",
"config": {
"forge": {
"packagerConfig": {
"osxSign": {
"identity": "Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)",
"hardened-runtime": true,
"entitlements": "entitlements.plist",
"entitlements-inherit": "entitlements.plist",
"signature-flags": "library"
},
"osxNotarize": {
"appleId": "felix@felix.fun",
"appleIdPassword": "my-apple-id-password"
}
}
}
}
}

The entitlements.plist file referenced here needs the following macOS-specific entitlements to assure the Apple security mechanisms that your app is doing these things without meaning any harm:此处引用的entitlementsp.list文件需要以下特定于macOS的权限,以确保Apple安全机制确保您的应用程序正在做这些事情,而不会造成任何伤害:

entitlements.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.debugger</key>
<true/>
</dict>
</plist>

Note that up until Electron 12, the com.apple.security.cs.allow-unsigned-executable-memory entitlement was required as well. 注意,在Electron 12之前,还需要com.apple.security.cs.allow-unsigned-executable-memory授权。However, it should not be used anymore if it can be avoided.然而,如果可以避免,就不应该再使用它。

To see all of this in action, check out Electron Fiddle's source code, especially its electron-forge configuration file.要查看所有这些操作,请查看Electron Fiddle的源代码,尤其是其electron-forge配置文件

If you plan to access the microphone or camera within your app using Electron's APIs, you'll also need to add the following entitlements:如果您计划使用Electron的API访问应用程序中的麦克风或摄像头,您还需要添加以下权利:

entitlements.plist
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>

If these are not present in your app's entitlements when you invoke, for example:如果您调用时应用程序的权利中没有这些内容,例如:

main.js
const { systemPreferences } = require('electron')
const microphone = systemPreferences.askForMediaAccess('microphone')

Your app may crash. 你的应用程序可能会崩溃。See the Resource Access section in Hardened Runtime for more information and entitlements you may need.有关您可能需要的更多信息和权利,请参阅强化运行时中的资源访问部分。

Using Electron Builder使用Electron Builder

Electron Builder comes with a custom solution for signing your application. Electron Builder附带了用于签署应用程序的自定义解决方案。You can find its documentation here.你可以在这里找到它的文档

Using Electron Packager使用Electron Packager

If you're not using an integrated build pipeline like Forge or Builder, you are likely using electron-packager, which includes electron-osx-sign and electron-notarize.如果您没有使用像Forge或Builder这样的集成构建管道,您可能会使用Electron打包器,其中包括electron-osx-signElectron公证

If you're using Packager's API, you can pass in configuration that both signs and notarizes your application.如果您使用的是Packager的API,则可以传入对应用程序进行签名和公证的配置

const packager = require('electron-packager')

packager({
dir: '/path/to/my/app',
osxSign: {
identity: 'Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)',
'hardened-runtime': true,
entitlements: 'entitlements.plist',
'entitlements-inherit': 'entitlements.plist',
'signature-flags': 'library'
},
osxNotarize: {
appleId: 'felix@felix.fun',
appleIdPassword: 'my-apple-id-password'
}
})

The entitlements.plist file referenced here needs the following macOS-specific entitlements to assure the Apple security mechanisms that your app is doing these things without meaning any harm:此处引用的entitlements.plist文件需要以下特定于macOS的权限,以确保Apple安全机制确保您的应用程序正在做这些事情,而不会造成任何伤害:

entitlements.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.debugger</key>
<true/>
</dict>
</plist>

Up until Electron 12, the com.apple.security.cs.allow-unsigned-executable-memory entitlement was required as well. 在Electron 12之前,还需要com.apple.security.cs.allow-unsigned-executable-memory授权。However, it should not be used anymore if it can be avoided.然而,如果可以避免,就不应该再使用它。

Signing Mac App Store applications签署Mac App Store应用程序

See the Mac App Store Guide.请参阅Mac App Store Guide

Signing Windows builds签署Windows生成

Before signing Windows builds, you must do the following:在签署Windows内部版本之前,必须执行以下操作:

  1. Get a Windows Authenticode code signing certificate (requires an annual fee)获取Windows Authenticode代码签名证书(需要年费)
  2. Install Visual Studio to get the signing utility (the free Community Edition is enough)安装Visual Studio以获取签名实用程序(免费社区版就足够了)

You can get a code signing certificate from a lot of resellers. 您可以从许多经销商处获得代码签名证书。Prices vary, so it may be worth your time to shop around. 价格各不相同,所以花时间逛街可能是值得的。Popular resellers include:受欢迎的经销商包括:

  • digicert
  • Sectigo
  • Amongst others, please shop around to find one that suits your needs!除此之外,请四处逛逛,寻找一款适合您需要的产品! 😄
Keep your certificate password private将证书密码保密

Your certificate password should be a secret. 您的证书密码应该是机密Do not share it publicly or commit it to your source code.不要公开共享或将其提交到源代码中。

Using Electron Forge使用Electron锻造

Once you have a code signing certificate file (.pfx), you can sign Squirrel.Windows and MSI installers in Electron Forge with the certificateFile and certificatePassword fields in their respective configuration objects.一旦您有了代码签名证书文件(.pfx),您就可以在Electron Forge中使用各自配置对象中的certificateFile和certificate Password字段对Squirrel.WindowsMSI安装程序进行签名。

For example, if you keep your Forge config in your package.json file and are creating a Squirrel.Windows installer:例如,如果您将Forge配置保存在package.json文件中,并正在创建SquirrelWindows安装程序:

package.json
{
"name": "my-app",
"version": "0.0.1",
//...
"config": {
"forge": {
"packagerConfig": {},
"makers": [
{
"name": "@electron-forge/maker-squirrel",
"config": {
"certificateFile": "./cert.pfx",
"certificatePassword": "this-is-a-secret"
}
}
]
}
}
//...
}

Using electron-winstaller使用Electron温控器 (Squirrel.Windows)

electron-winstaller is a package that can generate Squirrel.Windows installers for your Electron app. 是一个可以为您的Electron应用程序生成SquirrelWindows安装程序的软件包。This is the tool used under the hood by Electron Forge's Squirrel.Windows Maker. 这是Electron Forge的Squirrel.Windows Maker在引擎盖下使用的工具。If you're not using Electron Forge and want to use electron-winstaller directly, use the certificateFile and certificatePassword configuration options when creating your installer.如果您没有使用Electron Forge,并且希望直接使用electron-winstaller,请在创建安装程序时使用certificateFilecertificatePassword配置选项。

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',
certificateFile: './cert.pfx',
certificatePassword: 'this-is-a-secret',
})
console.log('It worked!')
} catch (e) {
console.log(`No dice: ${e.message}`)
}

For full configuration options, check out the electron-winstaller repository!要获得完整的配置选项,请查看electron-winstaller存储库!

Using electron-wix-msi (WiX MSI)使用Electronwix msi(wix msi)

electron-wix-msi is a package that can generate MSI installers for your Electron app. 是一个可以为Electron应用程序生成MSI安装程序的软件包。This is the tool used under the hood by Electron Forge's MSI Maker.这是Electron Forge的MSI Maker在发动机罩下使用的工具。

If you're not using Electron Forge and want to use electron-wix-msi directly, use the certificateFile and certificatePassword configuration options or pass in parameters directly to SignTool.exe with the signWithParams option.如果您没有使用Electron Forge,并且希望直接使用electron-wix-msi,请使用certificateFilecertificatePassword配置选项,或者使用signWithParams选项直接将参数传递给SignToolexe。

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',
certificateFile: './cert.pfx',
certificatePassword: 'this-is-a-secret',
})

// 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
supportBinaries.forEach(async (binary) => {
// 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()

For full configuration options, check out the electron-wix-msi repository!要获得完整的配置选项,请查看electron-wix-msi存储库!

Using Electron Builder使用Electron Builder

Electron Builder comes with a custom solution for signing your application. Electron Builder附带了用于签署应用程序的自定义解决方案。You can find its documentation here.你可以在这里找到它的文档

Signing Windows Store applications签署Windows应用商店应用程序

See the Windows Store Guide.请参阅Windows应用商店指南。