代理客户端、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 attestations | GitHub 记录的构建来源 | 所有项目都会提供 | 用 GitHub CLI 验证 |
如果一个项目只提供 SHA256,不要强行套 cosign 命令;如果项目已经给了签名文件,也不要只停在文件哈希。按 Release 实际提供的证据往上加一层就够。
第一步为什么是确认 owner、repo 和 tag?
很多下载错误不是文件坏了,而是入口错了。搜索结果里的同名项目、fork 仓库、旧版本 tag、第三方镜像页,都可能出现完全一样的文件名。
打开下载页时先记录 4 个字段:GitHub owner、repo、tag、文件名。比如 owner/repo、v1.2.3、mihomo-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 位。还要确认文件名完全一致,尤其是 amd64、arm64、windows、linux、darwin 这些平台字段。
checksums.txt 不匹配时先停在哪一步?
checksums.txt 不匹配,先不要安装,也不要立刻改客户端配置。按下面顺序排除:
- 文件是否来自同一个 tag。
- 清单里的文件名是否和本地文件名一致。
- 浏览器是否下载了重复文件,例如
client (1).zip。 - 压缩包是否被解压后再计算哈希。
- 是否从第三方页面下载了同名文件。
重新下载后仍然不匹配,就把该文件视为不可用。此时继续安装只会把问题带到客户端日志里,后面再排查订阅、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 URL | https://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。