簽署 macOS 應用程式

程式碼簽署是一項安全技術,您可以使用它來證明應用程式是由您建立的。

在 macOS 上,應用程式發佈有兩層安全技術:程式碼簽署公證

  • 程式碼簽署是證明應用程式作者身分,並確保應用程式在發佈前未被竄改的行為。

  • 公證是一個額外的驗證步驟,其中應用程式會被傳送到 Apple 伺服器進行自動惡意軟體掃描。

從 macOS 10.15 (Catalina) 開始,您的應用程式需要同時進行程式碼簽署和公證,才能在使用者機器上執行,而無需停用其他作業系統安全檢查。

Mac App Store (MAS) 應用程式是個例外,因為 MAS 提交過程涉及類似的自動檢查,因此不需要公證。

先決條件

安裝 Xcode

Xcode 是 Apple 用於在 macOS、iOS 和其他平台上開發的整合開發環境 (IDE)。

雖然 Electron 並未與 IDE 本身緊密整合,但 Xcode 是安裝程式碼簽署憑證(請參閱下一節)的實用工具,並且是公證必備的。

取得簽署憑證

macOS 應用程式的程式碼簽署憑證只能透過購買 Apple Developer Program 的會員資格,才能從 Apple 取得。

若要簽署 Electron 應用程式,您可能需要兩個不同的憑證

  • Developer ID Installer 憑證適用於發佈到 Mac App Store 的應用程式。

  • Developer ID Application 憑證適用於在 Mac App Store 之外發佈的應用程式。

取得 Apple Developer Program 會員資格後,您首先需要將憑證安裝到您的機器上。我們建議透過 Xcode 載入它們

驗證您的憑證已安裝

安裝憑證後,您可以使用下列 shell 命令在終端機中檢查可用的程式碼簽署憑證

security find-identity -p codesigning -v

設定 Forge

在 Electron Forge 中,macOS 應用程式會在封裝步驟中,由 electron-packager 函式庫進行簽署和公證。在 Forge packagerConfig 中,每個設定都有一個個別的選項。

osxSign 選項

在底層,Electron Forge 使用 @electron/osx-sign 工具來簽署您的 macOS 應用程式。

若要在 macOS 上啟用程式碼簽署,請確保您的 Forge 組態中存在 packagerConfig.osxSign

forge.config.js
module.exports = {
  packagerConfig: {
    osxSign: {} // object must exist even if empty
  }
};

osxSign 組態具有在大多數情況下都能開箱即用的預設值,因此我們建議您從空的組態物件開始。

如需組態選項的完整清單,請參閱 Forge API 文件中的 OsxSignOptions 類型。如需有關如何設定這些選項的更詳細資訊,請參閱 @electron/osx-sign 文件

自訂授權

修改預設 osxSign 組態的常見用途是自訂其授權。在 macOS 中,授權是授予應用程式特定功能的權限(例如,存取相機、麥克風或 USB 裝置)。這些權限會儲存在應用程式可執行檔的程式碼簽章中。

預設情況下,@electron/osx-sign 工具會隨附一組應適用於 MAS 或直接發佈目標的授權。請參閱 GitHub 上預設授權檔案的完整集合。

forge.config.js
module.exports = {
  // ...
  packagerConfig: {
    // ...
    osxSign: {
      optionsForFile: (filePath) => {
        // Here, we keep it simple and return a single entitlements.plist file.
        // You can use this callback to map different sets of entitlements
        // to specific files in your packaged app.
        return {
          entitlements: 'path/to/entitlements.plist'
        };
      }
    }
  }
  // ...
};

如需有關授權的進一步閱讀,請參閱 Apple 開發人員文件中的下列頁面

osxNotarize 選項

在底層,Electron Forge 使用 @electron/notarize 工具來公證您的 macOS 應用程式。

notarytool 命令有三個驗證選項,詳細說明如下。請注意,您需要使用 forge.config.js 組態,以便將環境變數載入到您的 Forge 組態中。

保持您的驗證詳細資料私密

您絕對不應將驗證資訊以純文字形式儲存在您的組態中。在下列範例中,憑證會儲存為環境變數,並透過 Node.js process.env 物件存取。

選項 1:使用應用程式專用密碼

您可以從 Apple 產生應用程式專用密碼,以向 notarytool 提供您的憑證。如果您變更您的 Apple ID 密碼,則需要重新產生此密碼。

如果您使用此策略,osxNotarize 有兩個強制欄位

欄位類型描述

appleId

字串

與您的 Apple 開發人員帳戶相關聯的 Apple ID

appleIdPassword

字串

應用程式專用密碼

teamId

字串

您想要進行公證的 Apple 團隊 ID。您可以前往 https://developer.apple.com/account/#/membership 找到您所屬團隊的團隊 ID。

forge.config.js
module.exports = {
  // ...
  packagerConfig: {
    // ...
    osxNotarize: {
      appleId: process.env.APPLE_ID,
      appleIdPassword: process.env.APPLE_PASSWORD,
      teamId: process.env.APPLE_TEAM_ID
    }
  }
  // ...
};

雖然名稱為 appleIdPassword,但它並非您的 Apple ID 帳戶密碼。

選項 2:使用 App Store Connect API 金鑰

您可以產生 App Store Connect API 金鑰來驗證 notarytool,方法是前往 App Store Connect 存取頁面 並使用「團隊金鑰」標籤。此 API 金鑰看起來會像 AuthKey_ABCD123456.p8,而且只能下載一次。

如果您使用此策略,則 osxNotarize 有三個必填欄位

欄位類型描述

appleApiKey

字串

您的 API 金鑰檔案的檔案系統路徑字串。

appleApiKeyId

字串

10 個字元的字母數字 ID 字串。在先前的 AuthKey_ABCD123456.p8 範例中,這會是 ABCD123456

appleApiIssuer

字串

識別 API 金鑰發行者的 UUID。您可以在產生 API 金鑰的「金鑰」標籤中找到此 ID。

forge.config.js
module.exports = {
  // ...
  packagerConfig: {
    // ...
    osxNotarize: {
      appleApiKey: process.env.APPLE_API_KEY,
      appleApiKeyId: process.env.APPLE_API_KEY_ID,
      appleApiIssuer: process.env.APPLE_API_ISSUER
    }
  }
  // ...
};

選項 3:使用鑰匙圈

您可以選擇使用 macOS 鑰匙圈,其中包含任一組憑證(上方選項 1 或選項 2),而不是將環境變數提供給傳遞給 notarytool 的 Forge 設定。

您可以直接在終端機中透過 notarytool store-credentials 命令執行此操作。如需使用資訊,您可以參考 notarytool 的手冊頁面

man notarytool

如果您使用此策略,則 osxNotarize 有兩個可用欄位

欄位類型描述

keychainProfile

字串

包含您的公證憑證的鑰匙圈設定檔名稱。

keychain (選用)

字串

包含具有您的憑證的設定檔的鑰匙圈名稱(或路徑)。

請注意,如果您使用 notarytool store-credentials,則可以自動偵測到 keychain 參數。

forge.config.js
module.exports = {
  // ...
  packagerConfig: {
    // ...
    osxNotarize: {
      keychainProfile: 'my-keychain-profile'
    }
  }
  // ...
};

範例設定

以下是 osxSignosxNotarize 的最小 Forge 設定。

forge.config.js
module.exports = {
  packagerConfig: {
    osxSign: {},
    osxNotarize: {
      appleId: process.env.APPLE_ID,
      appleIdPassword: process.env.APPLE_PASSWORD,
      teamId: process.env.APPLE_TEAM_ID
    }
  }
};

上次更新時間