Files
qiming/qimingclaw/crates/agent-electron-client/docs/windows-signing.md

310 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Windows 代码签名流程
本文档说明如何在本地对 Windows 安装包进行代码签名。
> ⚠️ **重要说明**:当前 Windows 客户端签名**仅支持本地手签方案**,不支持 CI/CD 自动化签名。
>
> 原因:使用 Certum SimplySign 云证书,需要通过手机 APP 获取动态 token 进行二次验证,无法在无人值守的 CI 环境中完成。
## 相关文件
| 文件 | 说明 |
|------|------|
| [sign-release-win.sh](./sign-release-win.sh) | 完整签名流程脚本 |
| [sign-win.js](./sign-win.js) | 签名工具模块 |
## 签名流程概览
```
┌──────────────────────────────────────────────────────────────────────────┐
│ Windows 客户端签名流程 │
├──────────────────────────────────────────────────────────────────────────┤
│ │
│ GitHub CI │
│ ┌─────────┐ │
│ │ Build │ ─── 构建 unsigned 安装包 ───▶ GitHub Release │
│ └─────────┘ (未签名) │
│ │
│ 本地手签 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │Download │───▶│ Sign │───▶│ Verify │───▶│ Upload │ │
│ │ (gh cli)│ │(signtool)│ │(signtool)│ │ (gh cli)│ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ unsigned/ unsigned/ signed/ GitHub Release │
│ (copy) (已签名) │
│ │
└──────────────────────────────────────────────────────────────────────────┘
```
## 前置要求
### 1. SimplySign Desktop 客户端
Certum 云代码签名证书需要安装 SimplySign Desktop 客户端来加载证书。
**下载地址:**
- Windows 64 位: https://www.certum.eu/data/other/SimplySign/SimplySignDesktop_x64.exe
- Windows 32 位: https://www.certum.eu/data/other/SimplySign/SimplySignDesktop_x86.exe
- Mac OS X: https://www.certum.eu/data/other/SimplySign/SimplySignDesktop.dmg
**安装步骤:**
1. 运行安装程序,语言选择 **English**
2. 安装路径可自定义
3. 组件选择时,仅勾选 **SimplySign Desktop**(不需要 proCertum SmartSign
**登录配置:**
1. 输入注册邮箱
2. 打开手机 SimplySign APP 获取 token 密码
3. 输入 token 完成登录
**获取证书指纹:**
1. 登录后软件最小化到系统托盘
2. 右键图标 → Manage certificates → Certificate list
3. 双击证书查看指纹 (Thumbprint)
### 2. Windows SDK
包含 `signtool.exe` 签名工具。
- 安装路径: `C:\Program Files (x86)\Windows Kits\10\bin\{version}\x64\`
- 下载: https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
### 3. GitHub CLI
用于下载和上传 release 文件:
```bash
gh auth status
```
## 环境变量配置
在签名前需要设置以下环境变量:
```bash
# 必需 - 证书指纹(从 SimplySign Desktop 中获取)
export WINDOWS_CERTIFICATE_SHA1="<your-certificate-thumbprint>"
# 可选(有默认值)
export WINDOWS_TIMESTAMP_URL="http://timestamp.sectigo.com"
export WINDOWS_PUBLISHER_NAME="成都第二空间智能科技有限公司"
```
> 💡 建议将环境变量添加到 `~/.bashrc` 或 `~/.bash_profile` 中持久化保存。
## 检查签名状态
在签名前,建议先检查 release 的签名状态,避免重复操作。
### 方法一:检查 Release 文件列表
```bash
# 查看 release 中的 Windows 安装包
gh release view electron-v0.9.2 --repo qiming-ai/qimingclaw --json assets \
--jq '.assets[] | select(.name | test("QimingClaw.*\\.(exe|msi)$")) | .name'
```
**判断标准:**
| 文件名模式 | 签名状态 | 操作 |
|-----------|---------|------|
| `*-unsigned.exe` / `*-unsigned.msi` | 未签名 | 需要执行签名 |
| `QimingClaw-Setup-x.x.x.exe` / `QimingClaw-x.x.x.msi` | 已签名 | 无需操作 |
### 方法二:下载并验证签名
```bash
# 下载文件到临时目录
mkdir -p /c/tmp/qimingclaw-sign/check && cd /c/tmp/qimingclaw-sign/check
gh release download electron-v0.9.2 --repo qiming-ai/qimingclaw \
--pattern "QimingClaw-Setup-*.exe" --pattern "QimingClaw-*.msi"
# 验证签名
"/c/Program Files (x86)/Windows Kits/10/bin/10.0.26100.0/x64/signtool.exe" \
verify //pa //all QimingClaw-Setup-0.9.2.exe
```
**输出解读:**
- `Successfully verified` → 已签名 ✓
- `SignerTool does not support...` 或错误 → 未签名或签名无效
## 使用方法
### 完整流程(推荐)
下载 → 签名 → 验证 → 上传:
```bash
cd crates/agent-electron-client
./scripts/build/sign-release-win.sh 0.9.2
```
### 跳过下载
如果已有未签名的文件:
```bash
./scripts/build/sign-release-win.sh 0.9.2 --skip-download
```
### 跳过上传
仅本地签名,不上传到 GitHub
```bash
./scripts/build/sign-release-win.sh 0.9.2 --skip-upload
```
### 组合使用
```bash
./scripts/build/sign-release-win.sh 0.9.2 --skip-download --skip-upload
```
## 多次构建/签名场景
### 场景一:同一版本重新打包后签名
如果 CI 重新构建了同一版本修复构建问题等release 中会出现新的 `-unsigned` 文件:
```
Release 资产列表:
├── QimingClaw-Setup-0.9.2.exe # 旧的已签名文件
├── QimingClaw-0.9.2.msi # 旧的已签名文件
├── QimingClaw-Setup-0.9.2-unsigned.exe # 新的未签名文件 (CI 重新构建)
└── QimingClaw-0.9.2-unsigned.msi # 新的未签名文件 (CI 重新构建)
```
**处理方式:** 直接运行签名脚本,它会:
1. 下载新的 `-unsigned` 文件
2. 签名后覆盖旧的已签名文件
3. 删除 `-unsigned` 文件
```bash
./scripts/build/sign-release-win.sh 0.9.2 # 正常执行即可
```
### 场景二:重新签名已签名的文件
如果需要重新签名(证书更新等),需要先让 CI 重新构建:
```bash
# 1. 触发 CI 重新构建(推送 tag 或手动触发)
# 2. CI 会生成新的 -unsigned 文件
# 3. 然后执行签名脚本
./scripts/build/sign-release-win.sh 0.9.2
```
> ⚠️ **注意**:不能直接对已签名的文件再次签名,需要从 CI 获取新的未签名文件。
### 场景三:检查是否需要签名
```bash
# 快速检查 release 中是否有 -unsigned 文件
gh release view electron-v0.9.2 --repo qiming-ai/qimingclaw --json assets \
--jq '.assets[] | select(.name | test("-unsigned\\.(exe|msi)$")) | .name'
# 有输出 → 需要签名
# 无输出 → 已签名或无 Windows 构建
```
## 目录结构
```
C:\tmp\qimingclaw-sign\
├── unsigned/ # 从 GitHub 下载的未签名文件
│ ├── QimingClaw-Setup-0.9.2-unsigned.exe
│ └── QimingClaw-0.9.2-unsigned.msi
└── signed/ # 已签名文件(重命名为正式名称)
├── QimingClaw-Setup-0.9.2.exe
└── QimingClaw-0.9.2.msi
```
## 文件命名规则
| 阶段 | EXE 文件名 | MSI 文件名 |
|------|-----------|-----------|
| CI 构建 | `QimingClaw-Setup-{version}-unsigned.exe` | `QimingClaw-{version}-unsigned.msi` |
| 本地签名后 | `QimingClaw-Setup-{version}.exe` | `QimingClaw-{version}.msi` |
## 流程步骤说明
| 步骤 | 命令/工具 | 说明 |
|------|-----------|------|
| Download | `gh release download` | 从 GitHub Release 下载 `.exe``.msi``unsigned/` |
| Sign | `signtool sign` | 使用证书进行代码签名(需要 SimplySign token |
| Verify | `signtool verify` | 验证签名有效性 |
| Copy | `cp` | 复制已签名文件到 `signed/` |
| Upload | `gh release upload` | 上传到 GitHub Release覆盖未签名文件 |
## 手动签名(可选)
如果需要单独签名某个文件:
```bash
# 设置 PATH包含 signtool
export PATH="/c/Program Files (x86)/Windows Kits/10/bin/10.0.26100.0/x64:$PATH"
# 设置环境变量
export WINDOWS_CERTIFICATE_SHA1="<your-certificate-thumbprint>"
export WINDOWS_TIMESTAMP_URL="http://timestamp.sectigo.com"
# 签名
node scripts/build/sign-win.js /path/to/file.exe
# 验证
signtool verify //pa //all /path/to/file.exe
```
## 常见问题
### Q: 为什么不支持 CI 自动签名?
Certum SimplySign 是云证书方案,需要通过手机 APP 获取动态 token 进行二次验证2FA这要求必须有人工参与无法在无人值守的 CI 环境中完成。
### Q: signtool 找不到?
确保已安装 Windows SDK脚本会自动搜索以下路径
- `C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64`
- `C:\Program Files (x86)\Windows Kits\10\bin\x64`
### Q: 证书未找到?
检查证书是否正确加载:
```powershell
# PowerShell - 列出所有代码签名证书
Get-ChildItem Cert:\CurrentUser\My | Where-Object { $_.EnhancedKeyUsageList -match "Code Signing" }
```
确保 SimplySign Desktop 已登录且证书已加载。
### Q: 网络超时?
下载或上传可能因网络问题超时,可以:
1. 使用 `--skip-download` 跳过下载
2. 使用 `--skip-upload` 跳过上传,稍后手动上传
### Q: MSI 签名失败?
确保下载的 MSI 文件完整(未截断)。检查文件大小是否合理(通常 > 100MB
### Q: NSIS 安装包完整性错误?
如果签名后的安装包运行时出现 "Installer integrity check has failed" 错误:
1. 验证下载文件 SHA256 是否正确
2. 重新下载原始文件
3. 检查原始 CI 构建是否有问题
## 参考链接
- [Certum SimplySign 使用教程](https://ssldun.net/html/guide_cn/show-1703.html)
- [SimplySign 证书提取](https://ssldun.net/html/guide_cn/show-1702.html)
## 更新日志
| 日期 | 说明 |
|------|------|
| 2026-03-26 | 添加签名状态检查和多次构建/签名场景说明 |
| 2026-03-26 | 创建签名流程文档,明确仅支持本地手签方案 |