← 返回目录

用 SignPath 给开源 Windows 应用免费做代码签名

不是软件有问题,而是它没有签名——在 Windows 看来,未签名的二进制文件是匿名的。买证书是一条路,但对开源项目来说,SignPath 提供的免费计划几乎是目前性价比最高的选择。

传统签名的模型,以及它的问题

传统签名的模型是:CA 把证书卖给你,你自己保管私钥,用 signtool 在本机或 CI 上签。问题是私钥一旦泄露(CI 日志、构建机、备份盘),攻击者就能以你的名义签名任何东西,而你能做的只有吊销证书。

传统签名与 SignPath 对比示意:传统模式下私钥在构建机或本地保存,SignPath 模式下私钥保存在 HSM 中,CI 只提交签名请求。
传统模式下私钥跟着构建机走;SignPath 模式下私钥只留在 HSM 里。

SignPath 是怎么工作的

SignPath 把传统模型倒了过来,核心思想可以概括成一句话:

私钥永远不出门,签名变成一个需要你「自证清白」的服务请求。
  1. 私钥由 SignPath 保管在硬件安全模块(HSM)中,从生成到销毁都不离开。
  2. 你的 CI 构建出产物(比如 Setup.exe),向 SignPath 提交一个签名请求。
  3. 关键的一步:SignPath 不签你上传的任意文件。它会验证这个产物确实来自你的源代码仓库——哪个 repo、哪个分支或 tag、哪个构建工作流、哪个构建系统(GitHub Actions、Jenkins、Azure DevOps 等)。这就是它说的 “Pipeline Integrity”(流水线完整性)。
  4. 验证通过后,用 HSM 里的私钥完成签名,签好的产物返回给你的流水线,继续发布。

所以签名传达的信息比一般证书更强:不仅「这个文件没被篡改」,还有「这个二进制确实是从那个公开仓库的某次 CI 构建出来的」。对开源项目来说,用户可以读到源码,又能验证下载的东西就是那套源码的产物——中间没有任何「相信我们」的环节。

顺带一提,它还能签的不只是 Windows 产物:MSI、EXE、DLL、PowerShell 脚本、NuGet 包、JAR、Docker 镜像、Office 宏都在支持列表里。

从零到签名:GitHub Actions + 开源免费计划

下面以 GitHub Actions + 开源免费计划为例,这是最顺畅的路径。

第一步:申请 SignPath Foundation 开源计划

在 signpath.io 的 Open Source 页面提交申请,需要提供:

  • 项目的 GitHub 仓库地址、下载页面地址、项目简介;
  • 开源许可证(要求 OSI 认可的协议,比如 MIT、GPL、Apache);
  • 一些能证明项目「真实、活跃、无恶意」的材料:GitHub stars、媒体报道、用户量等。

审核通常需要一到四周。在等待期间,可以先把构建流水线理顺——因为接下来 SignPath 要验证的就是这条流水线。

第二步:在 SignPath 控制台配置项目

审核通过后,在 dashboard 里建立 Project,需要记三个东西:

  • Project slug:项目标识;
  • Artifact configuration:描述你的产物(比如「一个 NSIS 安装包」),签名规则按它走;
  • Signing policy:签名的审批策略——开源计划里一般是「自动」(构建验证通过即签),企业版可以要求人工审批。

然后把你的仓库、工作流文件路径、分支/tag 规则(比如 refs/tags/v*)配置为可信构建系统。

第三步:接入 CI

官方提供 GitHub Action,接入大概长这样:

- name: Submit signing request to SignPath
  uses: signpath/github-action-submit-signing-request@v1
  with:
    api-token: ${{ secrets.SIGNPATH_API_TOKEN }}
    organization-id: ${{ secrets.SIGNPATH_ORG_ID }}
    project-slug: 'my-project'
    signing-policy-slug: 'release-signing'
    artifact-configuration-slug: 'installer'
    input-artifact-path: 'dist/MyApp-Setup.exe'
    wait-for-completion: true
    output-artifact-path: 'dist/MyApp-Setup-signed.exe'

如果不想等,也可以异步提交、稍后取回。除了 GitHub Action,还有 Jenkins 插件(submitSigningRequest / getSignedArtifact 两个 Pipeline 步骤)、Azure DevOps 集成、PowerShell 模块(Submit-SigningRequest),以及纯 REST API。把 SIGNPATH_API_TOKEN 和 SIGNPATH_ORG_ID 加进仓库的 secrets 后,推一个 tag 就能自动触发完整流程:构建 → 提交签名 → 取回签名产物 → 发布到 Releases。

第四步:验证

signtool verify /pa /v MyApp-Setup.exe

通过就说明签名链路已经打通。之后每次发版,Windows 用户看到的发布者一栏会是 SignPath Foundation,而不是你的名字——这是免费计划的代价,下面细说。

什么情形下该用它

适合:

  • 开源桌面应用的作者。 这是最契合的场景。免费的 OV 级证书、私钥零管理、CI 原生集成,换来的是用户不再看到 SmartScreen 警告、下载页更可信、杀毒软件误报明显减少。
  • 想要「可验证的发布链路」的项目。 因为签名绑定了「公开仓库 + CI 构建」的来源证明,它比「随便签个名」对用户的承诺更强。
  • 团队协作、有合规需求的商业项目。 付费版支持自己的证书、人工审批、签名审计日志、SLSA provenance 和 SBOM 证明,适合安全团队要求「每次签名可追溯」的组织。

不适合 / 要想清楚的:

  • 发布者名称是硬伤的场景。 免费计划的证书签发给 SignPath Foundation,用户看到的发布者不是你的名字。对个人开源项目这通常无所谓(甚至因为基金会的信誉而加分),但如果你在做商业闭源产品、需要发布者栏显示自己公司名,就得走付费计划(用自己的证书,HSM 仍由 SignPath 托管),或者干脆买传统证书。
  • 构建过程「不干净」的项目。 来源验证要求产物能明确追溯到公开仓库的 CI 构建。如果你的发布流程是「本机编译、手动上传网盘」,接入前得先把构建搬进 CI——这本身是件好事,但是工作量。
  • 急着上线的项目。 申请加审核可能要一个月,不适合「这周就要签名」的燃眉之急。
  • 指望签名后立刻不弹窗的项目。 别忘了上一篇的信誉机制:签名解决的是「匿名」问题,SmartScreen 的信誉仍要从零开始积累。SignPath 的证书因为是基金会签发、有多项目共用,初始信誉通常比个人新证书好,但上线初期少数用户仍可能看到警告——这和证书从哪来无关,是 Windows 的机制决定的。

结语

如果你是 Windows 桌面软件的开源作者,正在为 SmartScreen 弹窗和证书成本头疼,SignPath 的开源计划基本是目前性价比最高的路径:零成本、私钥安全有专业保障、还顺带强迫你把发布流水线做规范。它对独立开发者真正的价值不只是「免费的证书」,而是把「签名」从一个让你提心吊胆的安全责任,变成了一个 CI 里的普通步骤。

如果你的项目闭源、或者发布者署名对你很重要,那它仍然值得作为付费方案评估——HSM 托管 + 审批策略 + 审计日志,比自己维护硬件令牌现实得多。


参考资料:SignPath 官方文档(about.signpath.io)、SignPath GitHub Action 仓库、Jenkins SignPath 插件文档。本文基于 2026 年 9 月的产品信息撰写,具体申请条件以官网为准。签名机制的基础见上一篇《Windows 代码签名原理》。