如何用哈希验证文件完整性
当你下载软件、固件或重要文档时,如何知道文件正是发布者预期的内容?文件哈希给你一个加密指纹,一个只要文件相差一个字节就会改变的唯一字符串。验证哈希只需几秒钟,可以让你避免安装被篡改的软件、刷入会变砖的损坏固件,或信任一份在你真正需要恢复时会失败的损坏备份。
哈希函数简史
校验和的概念比计算本身更古老,会计师在出现可验证的文件之前就用数字位求和来检测抄写错误。加密哈希出现于 1980 年代末。Ron Rivest 在 1990 年发布了 MD4,1991 年发布了 MD5,后者在两十年里成为事实上的校验和。NIST 在 1993 年标准化了 SHA-0,但在发现缺陷后于 1995 年迅速将其撤回并采用 SHA-1。SHA-2 系列(SHA-224、SHA-256、SHA-384、SHA-512)在 2001 年跟进,以应对 SHA-1 迫近的弱点。
每一代都被比预期更便宜的攻击退役。MD5 碰撞在 2004 年得到展示,2008 年对数字证书变得实用,如今轻而易举。SHA-1 在 2017 年被 Google 的 SHAttered 攻击攻陷,研究者制造了两份具有相同 SHA-1 摘要的不同 PDF。SHA-2 自 2001 年以来一直挺住,SHA-3(Keccak,2015 年标准化)提供了一个结构上不同的备选,以防 SHA-2 哪天破裂。教训是哈希算法有保质期;今天合适的算法可能在十年内需要替换。
文件哈希如何工作
哈希函数读取文件的每个字节,产生一个固定长度的字符串。同一文件总产生同一哈希。改一个字节,哈希完全改变,这叫做雪崩效应,正是它让哈希对验证有用。
示例:
- 原始文件(SHA-256):
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 - 同一文件,一字节改变:
d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
即使两个文件只差一位,两个哈希也没有任何可识别的共同模式。这种敏感性正是让验证成为可能的原因:生成哈希、与已发布哈希比较,你就立即知道文件是否真实。
在内部,现代哈希函数把文件切成固定大小的块(SHA-256 是 64 字节,SHA-512 是 128 字节),把每个块送进一个压缩函数,并把状态向前链接。输出是混入最后一块后的最终状态。因为链依赖于每一个字节,没有任何捷径让攻击者能在不重写整个哈希的情况下改变内容。
如何验证一个文件
- 找到官方哈希,软件发布者通常在其下载页面列出文件哈希,常标记为「SHA-256 校验和」或「SHA256SUMS 文件」。
- 上传你下载的文件:在哈希计算器中选择文件。哈希在你的浏览器中本地计算;文件从不离开你的机器。
- 比较哈希:如果你计算的哈希与官方哈希完全一致,文件就是真实且未损坏的。如果字符串很长,把两者复制粘贴到文本差异工具中。
- 匹配算法:SHA-256 哈希只能与其他 SHA-256 哈希匹配。如果发布者给你 SHA-512,也生成 SHA-512;混淆算法是「不匹配」最常见的错误。
- 条件允许时验证已发布的哈希本身:一个签名的 SHA256SUMS 文件(用发布者的 GPG 密钥签名)告诉你哈希列表未被篡改,而下载页上的裸哈希做不到。
何时验证文件哈希
- 软件下载:验证安装包和更新在下载过程中未被篡改或损坏。任何向你提供二进制的角色,你的 ISP、CDN、镜像,理论上都可能换成恶意的东西。
- 固件更新:损坏的固件文件能让设备变砖。刷入路由器、IoT 设备或主板 BIOS 之前总要验证,恢复往往需要特殊硬件。
- ISO 映像:操作系统映像在烧录到 USB 或安装前应当验证。Linux 发行版普遍同时发布 SHA-256 哈希和对那些哈希的 GPG 签名;两者都验证。
- 法律和金融文档:验证合同、审计报告或财务报表在签署或共享后未被改动。哈希提供一份防篡改的回执。
- 备份验证,确认备份文件与原件一致。静默磁盘损坏是真实的,自创建以来哈希漂移的备份可能无法干净地恢复。
- CI/CD 工件:在部署流水线中用 SHA-256 锁定构建产物可保证你测试的二进制就是你部署的二进制。容器镜像通过其内容寻址摘要按设计做到这一点。
- 软件供应链审计:当一份安全公告说「该版本的哈希是 X」时,确认你服务器上是什么的唯一办法是在那里对文件做哈希再比较。否则你信任的是攻击者控制的版本字符串。
支持的算法
| 算法 | 哈希长度 | 输出位 | 建议 |
|---|---|---|---|
| MD5 | 32 个十六进制字符 | 128 | 仅遗留,已破,仅用于偶发性损坏 |
| SHA-1 | 40 个十六进制字符 | 160 | 仅遗留,已破,不要在安全场景信任 |
| SHA-224 | 56 个十六进制字符 | 224 | 小众;优先 SHA-256 |
| SHA-256 | 64 个十六进制字符 | 256 | 建议的通用标准 |
| SHA-384 | 96 个十六进制字符 | 384 | 高安全,用于 TLS 1.3 套件 |
| SHA-512 | 128 个十六进制字符 | 512 | SHA-2 的最大强度,在 64 位 CPU 上快 |
| SHA3-256 | 64 个十六进制字符 | 256 | 与 SHA-2 不同的内部设计,前瞻性 |
| BLAKE2b/BLAKE3 | 可变 | 256 或 512 | 最快的现代哈希,rsync、restic 在用 |
| CRC32 | 8 个十六进制字符 | 32 | 仅错误检测,不是安全哈希 |
如果你可以选择,SHA-256 是合理的默认。在 64 位机器上用 SHA-512 可略快(该算法面向 64 位字调优)。当吞吐最为关键时拿 BLAKE3,它能饱和现代 NVMe SSD,这是 SHA-256 做不到的。
哈希 vs 数字签名
哈希告诉你文件是否改变。数字签名告诉你它是否改变以及谁创建了哈希。签名是被发布者私钥加密的哈希;你用其公钥解密、重新计算哈希,然后检查二者是否一致。如果一致,你就知道文件完整,而且发布者(或持有其私钥的人)批准了它。
当下载页同时显示一个 SHA-256 哈希和一个 .sig 或 .asc 文件时,哈希防的是损坏与意外篡改,而签名防的是攻破下载服务器的攻击者。攻击者可以替换文件并更新显示的哈希;但没有发布者的密钥就无法伪造有效签名。
常见陷阱
- 比较了错的算法,MD5 与 SHA-256 产生的字符串长度不同;算法不匹配永远不会一致,哪怕文件相同。
- 信任与文件来自同一处的哈希,如果两者在同一被攻破的镜像上,两者都能被替换。尽量从不同域获取哈希(项目的 GitHub releases 页、已签名的 SHA256SUMS 文件)。
- 十六进制大小写敏感,哈希对大小写不敏感(
a3f与A3F表示同一字节)。字符串比较仍可能把它们标为不同。两边都改成小写或按字节比较。 - 尾随空白与 BOM,带尾换行或不可见字符的复制哈希看起来一致但不会匹配。比较前修剪两边。
- 哈希了错的文件,在 Windows 上,如果你下载了两次,路径可能是
下载\file (1).exe而非下载\file.exe。哈希前先核对路径。 - 把 MD5 或 SHA-1 当作安全保证,攻击者可在几秒内造出与恶意文件具有相同 MD5 的良性外观文件。出于安全考虑,始终使用 SHA-256 或更强。
- 验证了错的对象,如果发布者哈希的是压缩的
.tar.gz,而你哈希解压后的内容,二者都不会匹配。哈希被哈希过的东西;通常是下载的归档本身。 - 忽略 GPG 签名,很多人验证哈希但跳过签名。签名才是抵御控制镜像的攻击者的防线。
- 网络损坏的静默失败,如果两者都被同样地截断,截断的下载可能匹配部分文件的哈希。始终对你打算使用的完整文件做哈希,而不是一小块。
- 浏览器缓存了旧下载,过时的缓存文件可能欺骗验证步骤。如果哈希不匹配且你怀疑缓存,强制刷新下载。
替代工具与场景
当你只有一个文件要验证时,网页哈希计算器是最快的路径。对于重复使用或脚本化,命令行工具是标准。
| 工具 | 平台 | 优势 | 注意 |
|---|---|---|---|
| 网页哈希计算器 | 浏览器 | 免安装,文件从不上传 | 一次一个文件 |
sha256sum | Linux | 快、可脚本、GNU coreutils | --check 读取 SHA256SUMS 文件 |
shasum -a 256 | macOS、BSD | 自带,输出格式相同 | 与 Linux 上二进制名不同 |
Get-FileHash | Windows PowerShell | Windows 上一等公民 | 输出格式与 sha256sum 不同 |
certutil -hashfile | Windows cmd | 每个 Windows 都有 | 输出冗长需要解析 |
openssl dgst -sha256 | 跨平台 | 如果你已经有 OpenSSL | 比专用工具慢 |
b3sum | 跨平台 | BLAKE3,数 GB/s 吞吐 | 较新,不那么普及 |
rhash | 跨平台 | 一次计算多种算法 | 额外安装 |
在 CI/CD 流水线中,同一任务通常表现为构建时 sha256sum file > file.sha256,验证时 sha256sum -c file.sha256,有时包裹在一份签名清单里。原则(计算、发布、取回时比较)与浏览器工具在交互场景下做的事是一致的。
隐私与哈希计算器
哈希计算器完全在你的浏览器中运行。你选择的文件通过 FileReader API 读取,送入 Web Crypto SubtleCrypto 接口,结果哈希展示给你。文件的字节从不前往我们的服务器,没有上传、没有关于哪些文件被哈希的日志,也没有关于文件大小或扩展名的分析。对于敏感材料,合同、医疗记录、私钥,会上传的工具与本地哈希的工具之间的差别,就是信任一个第三方与不信任任何人的差别。哈希是一个微小输出(SHA-256 的 64 个十六进制字符),但它汇总的输入可能高度敏感。把那份输入保留在客户端是任何验证任务的合理默认。
常见问题
如何将文件哈希与官方的对比?
生成哈希后,与源(通常在下载页面)发布的哈希逐字符对比。如果所有字符都匹配,文件真实且未损坏。只要有一个差异都意味着文件被修改。
应使用哪种哈希算法?
SHA-256 是文件验证的标准。使用发布者提供的算法。如果您可以选择,SHA-256 在安全性和性能之间提供了良好平衡。
损坏的文件可能有正确的哈希吗?
理论上可能(碰撞),但在 SHA-256 下统计上可以忽略。几率如此微小,实际上相同的哈希保证文件相同。
我的文件会发送到服务器吗?
不会。哈希完全在您的浏览器中计算。您的文件从不离开您的设备,对任何类型的文档(包括敏感文档)都是安全的。
What is the difference between a hash and a digital signature?
A hash proves a file has not changed since the hash was computed; anyone can verify it. A digital signature proves both integrity AND identity, the publisher signs the hash with their private key, and you verify with their public key. Hashes alone do not protect against a hacker who replaced both the file and the published hash on the same compromised mirror.
Why are MD5 and SHA-1 considered insecure?
Researchers have demonstrated practical collision attacks for both. In 2017 Google produced two different PDFs with identical SHA-1 hashes (the SHAttered attack), and MD5 collisions can be generated in seconds on a laptop. For deliberate-tamper detection use SHA-256 or stronger; MD5 and SHA-1 still work for catching accidental corruption but should never be trusted as security boundaries.