验证开源软件包:从校验和到 GPG 签名
从开源项目下载二进制文件或源码压缩包时,常见的做法是“检查哈希”。这能确认文件没有在传输途中损坏,却不能证明文件确实出自合法的维护者。
对于关注安全的用户和开发者,验证应当是一条完整的流程:从完整性(文件是否发生变化?)走向真实性(是谁签署了这个文件?)。
基础:用校验和验证完整性
校验和(哈希)是第一道防线,可以检测意外损坏或简单的篡改。
常用命令
不同操作系统使用不同的工具来计算下载文件的哈希。
Linux(GNU Coreutils):
macOS:
局限
如果攻击者入侵了下载服务器,就可以同时替换二进制文件和 sha256sum.txt。两者的哈希仍然匹配,但你验证的已经是恶意文件。这就是需要密码学签名的原因。
关键:用 GPG 验证真实性
GPG 签名能证明某个私钥的持有者签署了文件。即使服务器被入侵,没有私钥的攻击者也无法伪造签名。
逐步验证
A. 获取公钥
验证签名需要维护者的公钥。注意: 从提供二进制文件的同一台服务器下载公钥存在风险。更稳妥的方式是通过独立的可信渠道获取密钥文件,然后导入。
B. 验证签名
软件包通常附有独立签名文件,例如 ASCII 文本格式的 package.tar.gz.asc,或二进制格式的 package.tar.gz.sig。
如何解读结果
你可能看到这样的输出:
关键提醒: “Good signature”只说明签名来自与你导入的公钥相对应的私钥。如果你导入的是一把冒充开发者的恶意密钥,签名仍然会显示为“Good”。
只有通过独立渠道核对了密钥指纹,“Good signature”才足以作为判断依据。 下一节介绍这个步骤。
信任缺口:确认密钥
PGP 最困难的部分是“带外验证”:通过独立渠道确认密钥。要真正建立信任,就应核对密钥指纹。
- 在项目官网或开发者可信的个人资料页找到指纹。
- 将它与导入的密钥进行比较:
如果指纹一致,就能确认拿到的是对应的公钥。
实际示例
示例一:LibreWolf(bsys6)
LibreWolf 提供带有具体版本号的二进制包,例如 librewolf-152.0.6-1-linux-x86_64-package.tar.xz。
操作流程:
- 下载二进制包和对应的签名文件。
- 从 LibreWolf 官方安全渠道获取公钥。
- 执行验证:
示例二:Restic
Restic 为发布版本提供签名,帮助确认备份工具本身没有被篡改。
操作流程:
- 下载二进制文件(例如
restic_0.19.1_linux_amd64.bz2)、SHA256SUMS和SHA256SUMS.asc。 - 导入 Restic 维护者的公钥,Key ID 为
91A6868BD3F7A907。 - 执行验证:
Restic 也会签署 Git 标签,可以直接验证标签签名:
注:签名有效时,GPG 会显示“Good signature from fd0 (Alexander Neumann)”。务必与 Restic 官方文档核对 Key ID(91A6868BD3F7A907),避免使用冒充的密钥进行验证。
开发者速查表
| 目标 | 命令 | 说明 |
|---|---|---|
| 检查 SHA256 | sha256sum <file> | macOS 使用 shasum -a 256 |
| 导入密钥 | gpg --import <file> 或 gpg --recv-keys <ID> | 可使用 hkps://keys.openpgp.org |
| 验证签名 | gpg --verify <sig> [file] | .asc 为文本格式,.sig 为二进制格式 |
| 检查指纹 | gpg --fingerprint <ID> | 与官方来源核对 |
| 导出公钥 | gpg --export -a <ID> | 用于分享自己的公钥 |