代理客户端、core 和规则文件经常以 zip、tar.gz、exe、apk、gz 这些格式出现在 Release 资产里。下载中断、浏览器缓存、同名 fork、旧 tag 复用文件名,都会让「文件看起来对」和「文件真的对」变成两回事。

校验的目标不是把流程弄复杂,而是在安装前回答两个问题:文件内容有没有变,文件是否来自你以为的那个项目。SHA256 解决第一类问题;cosign、minisign、attestations 负责补第二类证据。

先判断你拿到了哪些校验材料?

Release 里看到的材料能确认什么不能确认什么下一步
只有安装包或压缩包没有额外证据无法比对损坏或来源重新确认官方仓库和 tag
checksums.txt / SHA256SUMS文件内容是否一致发布者身份计算本地 SHA256
.sig / .minisig文件或清单是否由对应私钥签过公钥来源是否可信找项目文档里的公钥
.bundle / cosign 说明签名和身份信息命令参数是否适配本项目按项目 README 或 Release 说明执行
GitHub attestationsGitHub 记录的构建来源所有项目都会提供用 GitHub CLI 验证

如果一个项目只提供 SHA256,不要强行套 cosign 命令;如果项目已经给了签名文件,也不要只停在文件哈希。按 Release 实际提供的证据往上加一层就够。

第一步为什么是确认 owner、repo 和 tag?

很多下载错误不是文件坏了,而是入口错了。搜索结果里的同名项目、fork 仓库、旧版本 tag、第三方镜像页,都可能出现完全一样的文件名。

打开下载页时先记录 4 个字段:GitHub owner、repo、tag、文件名。比如 owner/repov1.2.3mihomo-linux-amd64.gz 这几个字段必须来自同一个 Release 页面。

如果你是给多台设备准备客户端或 core,先在一台测试机完成校验,再分发到其它设备。多端同时换文件时,可以把兼容 Clash / Singbox / V2Ray 的订阅保留为同一份基线输入,避免把订阅变化和程序文件变化混在一起。

SHA256 怎么算才不容易对错文件?

把下载文件和 checksums.txt 放在同一目录,先确认清单里确实有你的文件名,再计算本地 SHA256。

macOS / Linux 常用命令:

shasum -a 256 ./client.zip

Windows PowerShell 常用命令:

Get-FileHash .\client.zip -Algorithm SHA256

比对时看完整哈希,不要只看前 8 位。还要确认文件名完全一致,尤其是 amd64arm64windowslinuxdarwin 这些平台字段。

checksums.txt 不匹配时先停在哪一步?

checksums.txt 不匹配,先不要安装,也不要立刻改客户端配置。按下面顺序排除:

  1. 文件是否来自同一个 tag。
  2. 清单里的文件名是否和本地文件名一致。
  3. 浏览器是否下载了重复文件,例如 client (1).zip
  4. 压缩包是否被解压后再计算哈希。
  5. 是否从第三方页面下载了同名文件。

重新下载后仍然不匹配,就把该文件视为不可用。此时继续安装只会把问题带到客户端日志里,后面再排查订阅、DNS、TUN 都会失真。

GitHub attestations 怎么放进流程?

GitHub 官方文档把 release integrity 放在供应链安全流程里,核心是把 Release 资产和构建来源关联起来。项目如果启用了 attestations,优先按 Release 页面或项目文档给出的 gh 命令验证。

常见入口是 GitHub CLI:

gh release verify v1.2.3 -R owner/repo
gh release verify-asset v1.2.3 ./client.zip -R owner/repo

命令是否可用取决于项目是否发布了对应材料,也取决于你的 GitHub CLI 版本。验证失败时先看错误信息是「没有 attestation」,还是「资产不匹配」。前者说明项目没提供,后者才更接近文件或 tag 对错问题。

cosign 应该验证文件还是清单?

cosign 的用法由项目决定。有的项目签单个二进制,有的项目签 checksums.txt,还有的项目在 Release 说明里给 bundle、证书身份或 issuer 条件。

不要把别的项目命令直接复制过来。先看 Release 说明或 README 里有没有类似 cosign verify-blob 的示例,再把文件名、签名文件、bundle 参数替换成同一 tag 下的材料。

一个安全的检查顺序是:

检查点为什么重要
文件和签名来自同一 tag避免拿旧签名验新文件
命令里的文件名准确cosign 验证的是具体 blob
bundle 或证书参数照项目文档写不同项目的身份条件不同
先读错误信息再重跑失败原因可能是材料缺失,不一定是文件被改

如果项目没有提供 cosign 材料,就不要把「无法 cosign 验证」写成文件风险。只能说这个项目没有给这一层证据。

minisign 校验卡住通常是哪几个原因?

minisign 更常见的卡点是公钥来源。签名文件本身不够,用户还要拿到项目作者公开的 minisign 公钥。这个公钥应来自项目 README、官网或长期使用的发布说明,而不是某个临时评论。

常见命令形态类似:

minisign -Vm ./client.zip -P "public-key" -x ./client.zip.minisig

如果签的是 checksums.txt,就先验证清单,再用清单里的 SHA256 校验具体文件。不要把 .minisig 文件和另一个 tag 的压缩包混用。

什么时候该放弃这个 Release 文件?

出现下面几种情况,先停用这份下载文件:

  • SHA256 和同一 Release 的清单不匹配。
  • 签名文件、bundle 或公钥来自不同 tag。
  • 官方 Release 资产被删除后又重新上传,但项目没有说明。
  • 同名 fork 的 Release 比官方仓库更新,且没有可信迁移说明。
  • 验证命令明确提示资产不匹配。

停用不等于马上换客户端。更稳妥的做法是回到官方仓库,找前一个稳定 tag 或等待项目维护者补充说明。

怎么记录这次校验才方便下次复用?

记录一行就够,重点是让半年后的自己能复现:

字段示例写法
Release URLhttps://github.com/owner/repo/releases/tag/v1.2.3
文件名client-windows-amd64.zip
SHA256本地计算出的完整哈希
校验材料checksums.txt.minisig、cosign bundle 或 attestations
验证结果命令、时间、通过或失败原因

多人维护软路由、NAS 或家庭设备时,这一行记录比截图更有用。以后客户端无法启动,可以先判断是文件版本变化,还是订阅、规则、系统权限的问题。

相关阅读

FAQ

只校验 SHA256 够不够?

SHA256 能发现下载损坏和文件不一致,但不能单独证明发布者身份。项目只给 checksums.txt 时先用它;项目还给签名或 attestations 时,再补一层来源验证。

checksums.txt 也要校验吗?

checksums.txt 要从同一个 GitHub Release 下载,并核对 tag、文件名和发布时间。不要拿旧 tag 的清单校验新版本,也不要从评论区、网盘或第三方页面复制哈希。

cosign 和 minisign 有什么区别?

cosign 常见于 Sigstore 生态,验证时会关注签名、证书身份或 bundle;minisign 更轻量,通常靠项目给出的公钥校验文件或清单。用哪一个取决于项目发布材料。

签名验证失败是不是文件一定有问题?

不一定。常见原因包括文件名不匹配、签名文件下错 tag、公钥复制错误、命令参数缺少 bundle 或证书条件。先排除这些,再判断是否停止使用该文件。

代理客户端更新前要每次都校验吗?

手动下载 core、桌面客户端或软路由插件时建议校验,尤其是跨设备分发前。客户端内置更新器如果已经走官方机制,也可以只记录版本和 Release URL。