news 2026/10/11 2:34:32

跨平台二进制数字签名:在 GitHub Actions 中集成 Cosign 实现软件供应链防篡改

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
跨平台二进制数字签名:在 GitHub Actions 中集成 Cosign 实现软件供应链防篡改

在经历了 SolarWinds 供应链污染、XZ-utils 核心维护者后门注入等一系列触目惊心的全球网络安全事件后,开源软件的交付信任体系正在经历一场深刻的信任重构。

很多开源作者写好了一个 CLI 工具,在 GitHub Actions 里交叉编译出针对 Linux、macOS 和 Windows 的二进制包,打包成tar.gz挂在 Release 页面供用户下载。在这个看似自然的流转环节中,隐藏着一个巨大的软件供应链信任黑洞:
终端用户凭什么相信,从 GitHub Release 下载下来的二进制文件,就是由公开的源代码在纯净环境中构建出来的?

如果维护者的 GitHub 账号被黑、个人访问令牌(PAT)泄露,攻击者完全可以神不知鬼不觉地把 Release 附件里的二进制替换为一个捆绑了恶意挖矿或远控木马的恶意程序,而源码树上的代码依然显示得干干净净。

要彻底阻断这种篡改风险,必须为构建产物注入可公开密码学溯源的数字签名(Digital Signature)。

借助 Linux 基金会旗下 Sigstore 项目推出的Cosign工具与 GitHub Actions 的OIDC(OpenID Connect)无密钥签名机制(Keyless Signing),我们无需维护任何繁琐的传统 GPG 私钥,就能在 CI 流水线中实现真正透明、防篡改的软件供应链安全防线。

为什么传统的 GPG 签名走向没落

在过去,开源分发的标准做法是维护者用自己的 GPG 私钥对二进制进行本地签名,生成.asc文件。但在实际工程落地中,GPG 存在三个无法解决的硬伤:

  1. 私钥保管风险巨大:很多开发者把自己的 GPG 私钥导成明文 Base64 塞进 CI 的 Secrets 环境变量里。一旦第三方依赖或 CI 容器存在漏洞,私钥泄漏就意味着整个身份体系彻底崩溃。
  2. 信任锚点模糊(Web of Trust):用户下载了二进制和.asc,但由于没有全球权威的集中验证体系,用户根本不知道去哪里核实这个 GPG 公钥是不是维护者本人的,导致 99% 的普通用户直接跳过核验步骤。
  3. 缺少防抵赖的时间戳透明存证:攻击者拿到私钥后,可以任意伪造两年前的旧版本签名,难以证明签名行为发生的具体环境与上下文。

Cosign 无密钥签名的破局机理

Cosign 提出的“无密钥签名(Keyless Signing)”并不是真的不需要密钥,而是消灭了需要人类长期保管的静态私钥:

  1. OIDC 短期身份认领:在 GitHub Actions 运行过程中,Runner 通过id-token: write权限向 GitHub 的 OIDC 提供商申请一个有效期仅有数分钟的短期身份 JWT 令牌。该令牌中强绑定了当前代码仓库、Git 提交哈希、分支名称以及工作流文件路径。
  2. 临时公私钥对生成与签署:Cosign 在内存中生成临时的公私钥对,利用私钥对二进制构建产物(或校验和文件checksums.txt)进行签名。
  3. 短期证书签发(Fulcio CA):Cosign 将公钥与 OIDC 令牌提交给 Sigstore 的权威证书颁发机构 Fulcio。Fulcio 验证无误后,签发一张绑定了该 GitHub 身份的极短效 X.509 数字证书(有效期通常只有 10 分钟)。
  4. 公开透明日志存证(Rekor Transparency Log):签名记录、证书与元数据被永久写入公开的、只允许追加且防篡改的默克尔树账本 Rekor 中。
  5. 私钥立焚:签名完成的瞬间,内存中的临时私钥被彻底销毁,物理层面杜绝了私钥泄露的可能性。

落地配置:GitHub Actions 自动化签名流水线

我们以一个典型的 Go 多架构二进制发布流水线为例,展示如何在构建完成后自动完成 Cosign 签名并将证据链回传到 Release。

在.github/workflows/release-signed.yml中编写:

name: Secure Build & Sign Release on: push: tags: - 'v*' # 核心权限声明:必须开启 id-token: write 以便获取 GitHub OIDC 身份令牌 permissions: contents: write id-token: write jobs: build-and-sign: runs-on: ubuntu-latest steps: - name: Checkout Code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Go 1.27.1 uses: actions/setup-go@v5 with: go-version: '1.27.1' # 1. 安装 Cosign CLI 工具(锁定官方 Action 签名) - name: Install Cosign uses: sigstore/cosign-installer@v3.5.0 # 2. 执行跨平台构建并生成 SHA256 校验和清单 - name: Build Binaries run: | mkdir -p dist GOOS=darwin GOARCH=arm64 go build -trimpath -o dist/mycli-darwin-arm64 GOOS=linux GOARCH=amd64 go build -trimpath -o dist/mycli-linux-amd64 GOOS=windows GOARCH=amd64 go build -trimpath -o dist/mycli-windows-amd64.exe cd dist sha256sum * > checksums.txt cat checksums.txt # 3. 核心步骤:使用 Cosign 对校验和清单进行无密钥签名 - name: Sign Artifacts with Cosign run: | # 针对包含所有二进制哈希的 checksums.txt 进行签名 cosign sign-blob \ --yes \ --bundle dist/checksums.txt.bundle \ dist/checksums.txt # 4. 发布带密码学签名的 GitHub Release - name: Upload Release Assets uses: softprops/action-gh-release@v2 with: files: | dist/* env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

终端用户的极速安全核验

当用户从 GitHub Release 下载了客户端二进制后,如何用单行命令验证其绝对纯正?

用户只需要安装cosign,并在终端运行一条校验命令:

cosign verify-blob \ --bundle checksums.txt.bundle \ --certificate-identity "https://github.com/my-org/my-project/.github/workflows/release-signed.yml@refs/tags/v1.0.0" \ --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \ checksums.txt

如果校验通过,Cosign 会在终端输出一条绿色的确凿信息:

Verified OK The following checks were performed each of them must pass: - The identity was verified: https://github.com/my-org/my-project/... - The certificate was verified against the Fulcio roots. - The transaction was verified against the Rekor log.

随后,用户只需要本地比对刚下载二进制的哈希:

sha256sum -c checksums.txt --ignore-missing

这一整套链条在密码学层面提供了坚不可摧的证明:

  1. 防恶意篡改:任何人试图把恶意木马伪装成同名二进制挂在 Release 上,其计算出的哈希必然与被签名的checksums.txt不符;
  2. 防身份冒领:checksums.txt的签名证书是由 GitHub OIDC 权威证明的,确凿源自my-org/my-project的指定工作流,其他黑客即使拥有自己的 GitHub 账号也无法伪造出目标仓库的身份证书;
  3. 可审计存证:全世界任何人都可以通过公开的 Rekor 账本检索到某年某月某分某秒该发布行为的全部透明元数据。

将数字签名沉淀为交付的标准动作,是开源项目从“作坊式代码分发”迈向“企业级可信供应链”最重要的成年礼。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/11 2:34:29

SpringBoot+Vue3项目申报系统实战:从设计到部署的关键决策

做完整套项目申报系统,前后花了大约三周时间。这个项目的技术栈就是标题里列的:Java SpringBoot Vue3 MyBatis MySQL,前后端分离,典型的Web管理类项目。之所以选这套组合,不是因为追新,而是因为它足够稳…

作者头像 李华
网站建设 2026/10/11 2:33:59

Muse开源SDK:打破AI Agent的屏幕囚笼

1. 从 App Store 榜首到开源 SDK:一个信号,而非偶然事件“Muse 登顶 App Store 并开源 SDK”——这八个字背后没有一句多余的话,但信息密度极高。它不是又一个“AI 工具上线”的常规新闻,而是一次技术演进路径的显性确认&#xff…

作者头像 李华
网站建设 2026/10/11 2:31:04

Page Assist:本地运行DeepSeek模型的离线Web UI

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/11 2:28:27

IDEA 2024 配置 Tomcat 与 Servlet 全攻略:从版本选型到部署运行

第一次接触 Tomcat 和 Servlet,很多人都会在 IDEA 里兜圈子:代码明明照着写了,点运行却跳出 404;或者明明用的是老教程,放进新版 IDEA 却直接编译失败。 这类事情我前前后后折腾过很多回,每次帮朋友排查最后…

作者头像 李华
网站建设 2026/10/11 2:27:41

C# WinForms自绘漂亮登录窗体:无边框、圆角渐变与交互细节

简介:这份C#登录窗体资源是一套可直接参考的WinForms登录界面项目,面向桌面应用入门开发者及需要快速搭建账号登录模块的C#程序员。压缩包共70个文件,大小约550KB;11个.cs源文件配合4个.resx资源描述构成主工程核心,3个…

作者头像 李华
网站建设 2026/10/11 2:27:15

SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0全栈服装商城系统实战解析

搞Java Web电商类的项目,这两年最常见的需求就是“给我一个能跑、能看、能交差的全栈商城”。而网上服装商城这类带业务闭环的项目,正好是面试和毕设里出镜率最高的一种。今天这篇,我打算把手头这套SpringBoot2 Vue3 MyBatis-Plus MySQL8.…

作者头像 李华