跳至主要内容
版本: v2.9.0

代码签名

本指南介绍了如何在 MacOS 和 Windows 上签署使用 Wails 生成的二进制文件。本指南将针对 CI 环境,更具体地说是 GitHub Actions。

Windows

首先,您需要一个代码签名证书。如果您还没有,微软的信息页面列出了一些提供商 这里。请注意,除非您需要编写内核级软件(例如设备驱动程序),否则不需要 EV 证书。对于签署您的 Wails 应用程序,标准代码签名证书就可以了。

在针对自动构建系统之前,最好先检查一下您的证书提供商如何签署您本地机器上的二进制文件,以便您知道是否需要任何特殊要求。例如,这里 是 SSL.com 的 Windows 代码签名指南。如果您知道如何在本地签署,那么在 CI 环境中排查任何潜在问题将更容易。例如,SSL.com 代码签名证书需要 SignTool.exe/tr 标志,而其他提供商可能只需要 /t 标志来提供时间戳服务器。流行的 GitHub Actions 用于签署 Windows 二进制文件,例如 这个,不支持 SignTool.exe 的 /tr 标志。因此,本指南将重点介绍使用 PowerShell 命令手动签署我们的应用程序,但是如果您愿意,可以使用 code-sign-action Action 之类的操作。

首先,让我们确保我们能够在 GitHub CI 中构建我们的 Wails 应用程序。以下是一个小型工作流程模板

name: "example"
on:
workflow_dispatch:
# This Action only starts when you go to Actions and manually run the workflow.

jobs:
package:
strategy:
matrix:
platform: [windows-latest, macos-latest]
go-version: [1.18]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: setup node
uses: actions/setup-node@v2
with:
node-version: 14
# You may need to manually build you frontend manually here, unless you have configured frontend build and install commands in wails.json.
- name: Get Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: Build Wails app
run: |
wails build
- name: upload artifacts macOS
if: matrix.platform == 'macos-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-macos
path: build/bin/*
- name: upload artifacts windows
if: matrix.platform == 'windows-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-windows
path: build/bin/*

接下来,我们需要授予 GitHub 工作流程访问我们的签名证书的权限。这可以通过将您的 .pfx 或 .p12 证书编码为 base64 字符串来完成。要在 PowerShell 中执行此操作,您可以使用以下命令,假设您的证书名为 'my-cert.p12'

certutil -encode .\my-cert.p12 my-cert-base64.txt

现在您应该拥有包含 base64 编码证书的 .txt 文件。它应该以 -----BEGIN CERTIFICATE----- 开头,并以 -----END CERTIFICATE----- 结尾。现在您需要在 GitHub 上创建两个操作机密。导航到 设置 -> 机密 -> 操作 并创建以下两个机密

  • WIN_SIGNING_CERT,其中包含您的 base64 编码证书文本。
  • WIN_SIGNING_CERT_PASSWORD,其中包含您的证书密码。

现在我们已经准备好使用两种方法之一在我们的工作流程中实现签名

方法 1:使用命令签署

此方法使用 PowerShell 命令签署我们的应用程序,并让您控制整个签名过程。

"构建 Wails 应用程序" 步骤之后,我们可以将以下步骤添加到我们的工作流程中

- name: Sign Windows binaries
if: matrix.platform == 'windows-latest'
run: |
echo "Creating certificate file"
New-Item -ItemType directory -Path certificate
Set-Content -Path certificate\certificate.txt -Value '${{ secrets.WIN_SIGNING_CERT }}'
certutil -decode certificate\certificate.txt certificate\certificate.pfx
echo "Signing our binaries"
& 'C:/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x86/signtool.exe' sign /fd <signing algorithm> /t <timestamping server> /f certificate\certificate.pfx /p '${{ secrets.WIN_SIGNING_CERT_PASSWORD }}' <path to binary>

此脚本为您的证书文件创建一个新目录,从我们的 base64 机密创建证书文件,将其转换为 .pfx 文件,最后签署二进制文件。最后一行中的以下变量需要替换

  • 签名算法:通常为 sha256。
  • 时间戳服务器:用于您的证书的时间戳服务器的 URL。
  • 二进制文件路径:要签署的二进制文件的路径。

鉴于我们的 Wails 配置将 outputfilename 设置为“app.exe”,并且我们拥有来自 SSL.com 的证书,那么这就是我们的工作流程

name: "example"
on:
workflow_dispatch:
# This Action only starts when you go to Actions and manually run the workflow.

jobs:
package:
strategy:
matrix:
platform: [windows-latest, macos-latest]
go-version: [1.18]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: setup node
uses: actions/setup-node@v2
with:
node-version: 14
# You may need to manually build you frontend here, unless you have configured frontend build and install commands in wails.json.
- name: Get Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: Build Wails app
run: |
wails build
- name: Sign Windows binaries
if: matrix.platform == 'windows-latest'
run: |
echo "Creating certificate file"
New-Item -ItemType directory -Path certificate
Set-Content -Path certificate\certificate.txt -Value '${{ secrets.WIN_SIGNING_CERT }}'
certutil -decode certificate\certificate.txt certificate\certificate.pfx
echo "Signing our binaries"
& 'C:/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x86/signtool.exe' sign /fd sha256 /tr http://ts.ssl.com /f certificate\certificate.pfx /p '${{ secrets.WIN_SIGNING_CERT_PASSWORD }}' .\build\bin\app.exe

- name: upload artifacts macOS
if: matrix.platform == 'macos-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-macos
path: build/bin/*
- name: upload artifacts windows
if: matrix.platform == 'windows-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-windows
path: build/bin/*

方法 2:使用 Action 自动签署

可以使用 Windows 代码签名 Action,例如 这个,但请注意,它需要证书的 SHA1 哈希和证书名称。查看如何在 Action 的 市场 上配置它。


MacOS

首先,您需要从 Apple 获取您的代码签名证书。如果您还没有,简单的 Google 搜索将帮助您获得一个。获得证书后,您需要导出它并将其编码为 base64。 本教程 向您展示了如何以简单的方式执行此操作。导出 .p12 证书文件后,您可以使用以下命令将其编码为 base64,如教程中所示

base64 Certificates.p12 | pbcopy

现在您已准备好创建一些 GitHub 项目机密,就像 Windows 一样

  • APPLE_DEVELOPER_CERTIFICATE_P12_BASE64,其中包含您新复制的 base64 证书的内容。
  • APPLE_DEVELOPER_CERTIFICATE_PASSWORD,其中包含您的证书密码。
  • APPLE_PASSWORD,其中包含您 Apple-ID 帐户的应用程序专用密码,您可以在 这里 生成。

让我们确保我们能够在 GitHub Action 工作流程中构建我们的 Wails 应用程序。以下是一个小型模板

name: "example"
on:
workflow_dispatch:
# This Action only starts when you go to Actions and manually run the workflow.

jobs:
package:
strategy:
matrix:
platform: [windows-latest, macos-latest]
go-version: [1.18]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: setup node
uses: actions/setup-node@v2
with:
node-version: 14
# You may need to manually build you frontend here, unless you have configured frontend build and install commands in wails.json.
- name: Get Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: Build Wails app
run: |
wails build
- name: upload artifacts macOS
if: matrix.platform == 'macos-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-macos
path: build/bin/*
- name: upload artifacts windows
if: matrix.platform == 'windows-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-windows
path: build/bin/*

对于 macOS 上的代码签名, gon 是一款非常方便的代码签名和与 Apple 服务器通信的工具,也是用 Go 编写的,本指南将使用它。

构建 Wails 应用程序 步骤之后,将以下内容添加到工作流程中

- name: MacOS download gon for code signing and app notarization
if: matrix.platform == 'macos-latest'
run: |
brew install Bearer/tap/gon

现在我们需要在 build/darwin 目录中配置一些 gon 配置文件

  1. gon-sign.json
{
"source": ["./build/bin/app.app"],
"bundle_id": "app.myapp",
"apple_id": {
"username": "[email protected]",
"password": "@env:APPLE_PASSWORD",
"provider": "ABCDE12345"
},
"sign": {
"application_identity": "Developer ID Application: Human User"
}
}

以下是对上述字段的简要说明

  • source:要签署的 Wails 二进制文件的位置
  • apple_id:
    • username:您的 Apple ID 电子邮件地址
    • password:您的应用程序专用密码,使用 Gon 的环境变量语法引用
    • provider:您的 App Store Connect 帐户的团队 ID
  • sign:
    • application_identity:您的 Apple 开发者身份

您可以在 macOS 上通过运行以下命令找到您的开发者身份和团队 ID

$ security find-identity -v -p codesigning
1) 00000000000000000000000000000000000000000 "Developer ID Application: Human User (ABCDE12345)"
  1. 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.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
</dict>
</plist>

在此文件中,您可以配置应用程序所需的权利,例如,如果您的应用程序使用相机,则需要相机权限。阅读有关权利的更多信息 这里

确保您已使用与您在 gon-sign.json 中输入的捆绑包 ID 相同的捆绑包 ID 更新了 Info.plist 文件。以下是一个示例 Info.plist 文件

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>CFBundlePackageType</key><string>APPL</string>
<key>CFBundleName</key><string>MyApp</string>
<key>CFBundleExecutable</key><string>app</string>
<key>CFBundleIdentifier</key><string>app.myapp</string>
<key>CFBundleVersion</key><string>0.1.0</string>
<key>CFBundleGetInfoString</key><string>My app is cool and nice and chill and</string>
<key>CFBundleShortVersionString</key><string>0.1.0</string>
<key>CFBundleIconFile</key><string>iconfile</string>
<key>LSMinimumSystemVersion</key><string>10.13.0</string>
<key>NSHighResolutionCapable</key><string>true</string>
<key>LSApplicationCategoryType</key><string>public.app-category.utilities</string>
<key>NSHumanReadableCopyright</key><string>© Me</string>
</dict></plist>

现在我们已经准备好将签名步骤添加到我们在构建 Wails 应用程序之后的工作流程中

- name: Import Code-Signing Certificates for macOS
if: matrix.platform == 'macos-latest'
uses: Apple-Actions/import-codesign-certs@v1
with:
# The certificates in a PKCS12 file encoded as a base64 string
p12-file-base64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }}
# The password used to import the PKCS12 file.
p12-password: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }}
- name: Sign our macOS binary
if: matrix.platform == 'macos-latest'
run: |
echo "Signing Package"
gon -log-level=info ./build/darwin/gon-sign.json

请注意,使用 Apple 签署二进制文件可能需要几分钟到几个小时。

组合工作流程文件:

以下是我们包含 Windows + macOS 的 GitHub 工作流程文件

name: "example combined"
on:
workflow_dispatch:
# This Action only starts when you go to Actions and manually run the workflow.

jobs:
package:
strategy:
matrix:
platform: [windows-latest, macos-latest]
go-version: [1.18]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: setup node
uses: actions/setup-node@v2
with:
node-version: 14
# You may need to manually build you frontend here, unless you have configured frontend build and install commands in wails.json.
- name: Get Wails
run: go install github.com/wailsapp/wails/v2/cmd/wails@latest
- name: Build Wails app
run: |
wails build
- name: MacOS download gon for code signing and app notarization
if: matrix.platform == 'macos-latest'
run: |
brew install Bearer/tap/gon
- name: Import Code-Signing Certificates for macOS
if: matrix.platform == 'macos-latest'
uses: Apple-Actions/import-codesign-certs@v1
with:
# The certificates in a PKCS12 file encoded as a base64 string
p12-file-base64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }}
# The password used to import the PKCS12 file.
p12-password: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }}
- name: Sign our macOS binary
if: matrix.platform == 'macos-latest'
run: |
echo "Signing Package"
gon -log-level=info ./build/darwin/gon-sign.json
- name: Sign Windows binaries
if: matrix.platform == 'windows-latest'
run: |
echo "Creating certificate file"
New-Item -ItemType directory -Path certificate
Set-Content -Path certificate\certificate.txt -Value '${{ secrets.WIN_SIGNING_CERT }}'
certutil -decode certificate\certificate.txt certificate\certificate.pfx
echo "Signing our binaries"
& 'C:/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x86/signtool.exe' sign /fd sha256 /tr http://ts.ssl.com /f certificate\certificate.pfx /p '${{ secrets.WIN_SIGNING_CERT_PASSWORD }}' .\build\bin\Monitor.exe
- name: upload artifacts macOS
if: matrix.platform == 'macos-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-macos
path: build/bin/*
- name: upload artifacts windows
if: matrix.platform == 'windows-latest'
uses: actions/upload-artifact@v2
with:
name: wails-binaries-windows
path: build/bin/*

结束语

本指南的灵感来自 RiftShare 项目及其工作流程,强烈建议您查看 这里