跳到主要內容

程式碼簽署

程式碼簽署是一種安全技術,用於證明應用程式是由您所建立。您應該簽署您的應用程式,使其不會觸發任何作業系統安全警告。

macOS Sonoma Gatekeeper warning: The app is damaged

Windows 和 macOS 都會阻止使用者執行未簽署的應用程式。雖然可以發佈未進行程式碼簽署的應用程式,但為了執行這些應用程式,使用者需要執行多個進階且手動的步驟。

如果您正在建構計畫封裝和發佈的 Electron 應用程式,則應進行程式碼簽署。Electron 生態系統工具使簽署您的應用程式變得簡單明瞭 - 本文件說明如何在 Windows 和 macOS 上簽署您的應用程式。

macOS 建置版本的簽署與公證

準備 macOS 應用程式以供發佈需要兩個步驟:首先,應用程式需要進行程式碼簽署。然後,應用程式需要上傳到 Apple 進行稱為公證的程序,其中自動化系統將進一步驗證您的應用程式是否沒有執行任何危害使用者的行為。

要開始此程序,請確保您符合應用程式簽署和公證的要求

  1. 註冊 Apple 開發者計畫 (需要年費)
  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: 'felix@felix.fun',
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 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/packagerelectron-winstallerelectron-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 商店應用程式

請參閱 Windows 商店指南