代码签名 #
一、签名概述 #
1.1 为什么需要签名 #
| 原因 | 说明 |
|---|---|
| 安全验证 | 确保应用来源可信 |
| 防止篡改 | 检测应用是否被修改 |
| 系统信任 | 避免安全警告 |
| 应用商店 | 上架必要条件 |
1.2 各平台签名要求 #
| 平台 | 签名类型 | 说明 |
|---|---|---|
| Windows | Authenticode | 需要代码签名证书 |
| macOS | Developer ID | 需要 Apple 开发者账号 |
| Linux | GPG | 可选,用于验证 |
二、Windows 签名 #
2.1 获取证书 #
text
证书类型:
- EV 代码签名证书:最高信任级别
- OV 代码签名证书:标准信任级别
证书颁发机构:
- DigiCert
- Sectigo
- GlobalSign
2.2 配置签名 #
json
// tauri.conf.json
{
"bundle": {
"windows": {
"certificateThumbprint": "your-certificate-thumbprint",
"digestAlgorithm": "sha256",
"timestampUrl": "http://timestamp.digicert.com",
"signCommand": {
"cmd": "signtool",
"args": [
"sign",
"/fd", "sha256",
"/sha1", "your-certificate-thumbprint",
"/t", "http://timestamp.digicert.com",
"/v"
]
}
}
}
}
2.3 使用 SignTool #
bash
# 基本签名
signtool sign /fd sha256 /sha1 YOUR_THUMBPRINT /t http://timestamp.digicert.com app.exe
# 使用证书文件
signtool sign /fd sha256 /f certificate.pfx /p password /t http://timestamp.digicert.com app.exe
2.4 环境变量签名 #
bash
# 设置环境变量
export TAURI_SIGNING_PRIVATE_KEY="your-private-key"
export TAURI_SIGNING_PRIVATE_KEY_PASSWORD="your-password"
# 构建
pnpm tauri build
2.5 Azure Key Vault #
json
{
"windows": {
"signCommand": {
"cmd": "azuresigntool",
"args": [
"sign",
"--azure-key-vault-url", "https://your-vault.vault.azure.net",
"--azure-key-vault-client-id", "your-client-id",
"--azure-key-vault-client-secret", "your-client-secret",
"--azure-key-vault-certificate", "your-certificate-name",
"--timestamp-url", "http://timestamp.digicert.com",
"--file-digest", "sha256"
]
}
}
}
三、macOS 签名 #
3.1 准备工作 #
text
1. 注册 Apple Developer Program
2. 获取 Developer ID Application 证书
3. 安装 Xcode
4. 配置开发者账号
3.2 配置签名 #
json
// tauri.conf.json
{
"bundle": {
"macOS": {
"signingIdentity": "Developer ID Application: Your Name (TEAM_ID)",
"providerShortName": "TEAM_ID",
"hardenedRuntime": true,
"entitlements": "entitlements.plist"
}
}
}
3.3 Entitlements 配置 #
xml
<!-- 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.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
</plist>
3.4 公证 #
bash
# 构建应用
pnpm tauri build
# 创建 ZIP
ditto -c -k --keepParent "src-tauri/target/release/bundle/macos/MyApp.app" "MyApp.zip"
# 提交公证
xcrun notarytool submit "MyApp.zip" \
--apple-id "your@email.com" \
--team-id "TEAM_ID" \
--password "app-specific-password" \
--wait
# Staple 公证结果
xcrun stapler staple "src-tauri/target/release/bundle/macos/MyApp.app"
3.5 自动化公证 #
yaml
# .github/workflows/release.yml
name: Release macOS
on: [release]
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Build
run: pnpm tauri build
- name: Notarize
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
ditto -c -k --keepParent "src-tauri/target/release/bundle/macos/MyApp.app" "MyApp.zip"
xcrun notarytool submit "MyApp.zip" --apple-id "$APPLE_ID" --team-id "$APPLE_TEAM_ID" --password "$APPLE_PASSWORD" --wait
xcrun stapler staple "src-tauri/target/release/bundle/macos/MyApp.app"
四、Linux 签名 #
4.1 GPG 签名 #
bash
# 生成 GPG 密钥
gpg --full-generate-key
# 列出密钥
gpg --list-keys
# 导出公钥
gpg --armor --export your@email.com > public.key
4.2 签名 DEB 包 #
bash
# 构建
pnpm tauri build
# 签名
dpkg-sig -k your@email.com --sign builder src-tauri/target/release/bundle/deb/myapp_1.0.0_amd64.deb
4.3 签名 AppImage #
bash
# 使用 gpg2 签名
gpg2 --armor --detach-sign myapp.AppImage
# 验证签名
gpg2 --verify myapp.AppImage.sig myapp.AppImage
五、CI/CD 签名 #
5.1 GitHub Actions #
yaml
name: Build and Sign
on: [push]
jobs:
build-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Install certificate
run: |
echo "${{ secrets.WINDOWS_CERTIFICATE }}" | base64 -d > certificate.pfx
certutil -importpfx certificate.pfx "${{ secrets.WINDOWS_CERT_PASSWORD }}"
- name: Build
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.WINDOWS_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.WINDOWS_KEY_PASSWORD }}
run: pnpm tauri build
build-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Install certificate
env:
CERTIFICATE_BASE64: ${{ secrets.MACOS_CERTIFICATE }}
CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERT_PASSWORD }}
run: |
echo $CERTIFICATE_BASE64 | base64 -d > certificate.p12
security create-keychain -p actions temp.keychain
security import certificate.p12 -k temp.keychain -P $CERTIFICATE_PASSWORD -T /usr/bin/codesign
security set-key-partition-list -S apple-tool:,apple: -s -k actions temp.keychain
- name: Build
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
pnpm tauri build
# 公证步骤...
5.2 安全存储密钥 #
text
GitHub Secrets:
- WINDOWS_CERTIFICATE: Base64 编码的证书
- WINDOWS_CERT_PASSWORD: 证书密码
- MACOS_CERTIFICATE: Base64 编码的证书
- MACOS_CERT_PASSWORD: 证书密码
- APPLE_ID: Apple ID
- APPLE_PASSWORD: App 专用密码
- APPLE_TEAM_ID: 团队 ID
六、验证签名 #
6.1 Windows 验证 #
powershell
# 使用 SignTool 验证
signtool verify /pa /all app.exe
# 使用 PowerShell
Get-AuthenticodeSignature app.exe
6.2 macOS 验证 #
bash
# 验证签名
codesign --verify --deep --strict --verbose=2 MyApp.app
# 验证公证
spctl --assess --verbose --type execute MyApp.app
6.3 Linux 验证 #
bash
# 验证 GPG 签名
gpg --verify package.deb.sig package.deb
七、最佳实践 #
7.1 证书管理 #
text
1. 使用硬件令牌存储证书
2. 限制证书访问权限
3. 定期轮换证书
4. 使用 CI/CD 密钥管理
7.2 签名流程 #
text
1. 本地开发时不签名
2. CI/CD 中自动签名
3. 发布前验证签名
4. 记录签名信息
7.3 错误处理 #
bash
# Windows 签名失败
signtool sign /debug ...
# macOS 签名失败
codesign --verify --verbose=4 MyApp.app
八、总结 #
8.1 核心要点 #
| 要点 | 说明 |
|---|---|
| Windows | Authenticode 签名 |
| macOS | Developer ID + 公证 |
| Linux | GPG 签名(可选) |
| CI/CD | 自动化签名流程 |
| 密钥管理 | 安全存储证书 |
8.2 下一步 #
现在你已经掌握了代码签名,接下来让我们学习 多平台构建,了解如何构建跨平台应用!
最后更新:2026-03-28