代码签名

代码签名是一种用来证明应用是由你创建的一种安全技术。

macOS 系统能通过代码签名检测对app的任何修改,包括意外修改和来自恶意代码的修改。

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. Trust level builds over time so it’s better to start code signing as early as possible.

即使开发者可以发布一个未签名的应用程序,但是我们并不建议这样做。 Both Windows and macOS will, by default, prevent either the download or the execution of unsigned applications. Starting with macOS Catalina (version 10.15), users have to go through multiple manual steps to open unsigned applications.

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

如你所见,用户有两个选择:直接删除应用或者取消运行。 你不会想让用户看见该对话框。

如果你正在开发一款Electron应用,并打算将其打包发布,那你就应该为其添加代码签名。

Signing & notarizing macOS builds

Properly preparing macOS applications for release requires two steps: 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. 加入 Apple Developer Program(需要缴纳年费)
  2. Download and install Xcode - this requires a computer running macOS
  3. 生成,下载,然后安装签名证书(signing certificates)

Electron’s ecosystem favors configuration and freedom, so there are multiple ways to get your application signed and notarized.

electron-forge

If you’re using Electron’s favorite build tool, getting your application signed and notarized requires a few additions to your configuration. Forge is a collection of the official Electron tools, using [electron-packager], [electron-osx-sign], and [electron-notarize] under the hood.

Let’s take a look at an example configuration with all required fields. 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.

  1. {
  2. "name": "my-app",
  3. "version": "0.0.1",
  4. "config": {
  5. "forge": {
  6. "packagerConfig": {
  7. "osxSign": {
  8. "identity": "Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)",
  9. "hardened-runtime": true,
  10. "entitlements": "entitlements.plist",
  11. "entitlements-inherit": "entitlements.plist",
  12. "signature-flags": "library"
  13. },
  14. "osxNotarize": {
  15. "appleId": "felix@felix.fun",
  16. "appleIdPassword": "my-apple-id-password",
  17. }
  18. }
  19. }
  20. }
  21. }

The 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:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3. <plist version="1.0">
  4. <dict>
  5. <key>com.apple.security.cs.allow-jit</key>
  6. <true/>
  7. <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
  8. <true/>
  9. <key>com.apple.security.cs.debugger</key>
  10. <true/>
  11. </dict>
  12. </plist>

To see all of this in action, check out Electron Fiddle’s source code, especially its electron-forge configuration file.

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:

  1. <key>com.apple.security.device.audio-input</key>
  2. <true/>
  3. <key>com.apple.security.device.camera</key>
  4. <true/>

If these are not present in your app’s entitlements when you invoke, for example:

  1. const { systemPreferences } = require('electron')
  2. 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.

electron-builder

Electron Builder comes with a custom solution for signing your application. You can find its documentation here.

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].

If you’re using Packager’s API, you can pass in configuration that both signs and notarizes your application.

  1. const packager = require('electron-packager')
  2. packager({
  3. dir: '/path/to/my/app',
  4. osxSign: {
  5. identity: 'Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)',
  6. 'hardened-runtime': true,
  7. entitlements: 'entitlements.plist',
  8. 'entitlements-inherit': 'entitlements.plist',
  9. 'signature-flags': 'library'
  10. },
  11. osxNotarize: {
  12. appleId: 'felix@felix.fun',
  13. appleIdPassword: 'my-apple-id-password'
  14. }
  15. })

The 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:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3. <plist version="1.0">
  4. <dict>
  5. <key>com.apple.security.cs.allow-jit</key>
  6. <true/>
  7. <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
  8. <true/>
  9. <key>com.apple.security.cs.debugger</key>
  10. <true/>
  11. </dict>
  12. </plist>

Mac App Store

See the Mac App Store Guide.

签署windows应用程序

在签署Windows应用程序前,你需要完成以下事项:

  1. Get a Windows Authenticode code signing certificate (requires an annual fee)
  2. Install Visual Studio to get the signing utility (the free Community Edition is enough)

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
  • Comodo
  • GoDaddy
  • Amongst others, please shop around to find one that suits your needs, Google is your friend 😄

你可以运用许多方式来签署你的应用:

  • [electron-winstaller] will generate an installer for windows and sign it for you
  • [electron-forge] can sign installers it generates through the Squirrel.Windows or MSI targets.
  • [electron-builder] 能签署一些windows安装包。

Windows Store

参考 Windows Store Guide.