代码签名
这是有关如何在 MacOS 和 Windows 上对使用 Wails 生成的二进制文件进行签名的指南。 该指南将针对 CI 环境,更具体地说是 GitHub Actions。
Windows
首先,您需要一个代码签名证书。 如果您还没有,Microsoft 的信息页面会 在此处 列出一些提供商。 请注意,除非您需要编写内核级软件,例如设备驱动程序,否则不需要 EV 证书。 为了签署你的 Wails 应用程序,一个标准的代码签名证书就可以了。
在针对自动构建系统之前,与您的证书提供商核实如何在您的本地计算机上签署您的二进制文件可能是一个好主意,这样您就知道是否有任何特殊要求。 例如,这里 是 SSL.com 的 Windows 代码签名指南。 如果您知道如何在本地签名,则可以更轻松地解决 CI 环境中的任何潜在问题。 例如,SSL.com 代码签名证书需要 SignTool.exe 的 /tr
标志, 而其他提供商可能只需要 /tr
标志来提供时间戳服务器。 用于签署 此类 Windows 二进制文件的流行 GitHub Actions 不支持 SignTool.exe 上的 /tr
标志。 因此,本指南将重点介绍使用 PowerShell 命令手动签署我们的应用程序,但如果您愿意,可以使用类似 代码签名操作 的操作。
首先,让我们确保我们能够在我们的 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 上创建两个 action secret。 导航到 Settings -> Secrets -> Actions 并创建以下两个 secrets:
- WIN_SIGNING_CERT 您的 base64 编码证书文本的内容。
- WIN_SIGNING_CERT_PASSWORD 您的证书密码的内容。
现在我们准备好使用以下两种方法之一在我们的工作流程中实现签名:
方法一:使用命令签名
此方法使用 PowerShell 命令对我们的应用程序进行签名,并让您控制整个签名过程。
在该 "Build Wails app"
步骤之后,我们可以将以下步骤添加到我们的工作流程中:
- 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/*
方法二:Action自动签名
可以使用像 这样 的 Windows 代码签名操作,但请注意,它需要证书的 SHA1 哈希和证书名称。 查看如何在 Action 的 市场 上配置它的示例。
MacOS
首先,您需要 Apple 提供的代码签名证书。 如果您没有,简单的谷歌搜索将帮助您获得一个。 获得证书后,您需要将其导出并将其编码为 base64。 本 教程 向您展示了如何以简单的方式做到这一点。 导出 .p12 证书文件后,您可以使用以下命令将其编码为 base64,如教程中所示:
base64 Certificates.p12 | pbcopy
现在您已准备好创建一些 GitHub 项目 secrets,就像在 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/*
For code signing on macOS, gon is a very handy tool for code signing and communicating with Apple servers, also written in Go, and will be used in this guide.
在 Build Wails 应用
步骤之后,将以下内容添加到工作流中:
- name: MacOS download gon for code signing and app notarization
if: matrix.platform == 'macos-latest'
run: |
brew install Bearer/tap/gon
Now we need to configure some gon config files in our build/darwin
directory:
- 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"
}
}
Here is a brief break down of the above fields:
source
: The location of your wails binary to be signedapple_id
:username
: Your Apple ID email addresspassword
: Your app-specific password, referenced using Gon's environment variable syntaxprovider
: Your team ID for your App Store Connect account
sign
:application_identity
: Your Apple developer identity
Your developer identity and team ID can both by found on macOS by running the following command:
$ security find-identity -v -p codesigning
1) 00000000000000000000000000000000000000000 "Developer ID Application: Human User (ABCDE12345)"
- 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 更新了 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 项目及其工作流程的启发,强烈建议在 此处 查看。