文件哈希校验完全指南:MD5/SHA-1/SHA-256 选哪个
MD5 已被破解但仍能查重、SHA-1 也已淘汰、SHA-256 当前安全、SHA-3 新一代。本指南讲清楚算法选型、HMAC 用法、防篡改与数字签名、性能对比、Web Crypto API 浏览器内计算。
下载大文件时,网站通常提供 SHA-256 哈希供你验证下载完整性。但为什么是 SHA-256 而不是 MD5?MD5 为什么被破解后还有人用?本指南从哈希算法原理讲起,覆盖 MD5/SHA-1/SHA-256/SHA-3 的安全演化、何时该用哪个、HMAC 与数字签名的应用、以及如何在浏览器内用 Web Crypto API 快速计算文件哈希。
哈希算法的基本原理与四大属性
哈希函数(Hash Function)是一种单向函数,把任意长度的输入映射到固定长度的输出(称为"哈希值"或"指纹")。
- 确定性:同样输入永远同样输出(100 次计算哈希都是 SHA256(file) = 同一个值)
- 不可逆:不能从哈希值反推原始输入(所有哈希算法都这样)
- 雪崩效应:改动输入 1 个字节,哈希值完全变化(这是防篡改的关键)
- 碰撞困难:不同输入产生同样哈希值极其困难(理想情况下"不可能")
安全哈希 vs 非安全哈希: - 非安全:CRC32(只用于 ZIP 检测错误),能轻易碰撞 - 安全:MD5/SHA 系列,需要极大计算资源才能人工构造碰撞
下载文件时的校验就是利用属性 3 和 4:网站发布 SHA-256(file),你本地计算相同哈希,相等则文件完整未被篡改。
MD5:33 岁的老将,已报废但仍在用
MD5 在 1992 年发布,被广泛使用 20+ 年。输出 128 位(32 个十六进制字符)。
为什么报废: - 2004 年发现理论碰撞(花了 64 台计算机一小时) - 2005 年 Dobbertin 的暴力碰撞 - 2009 年 CM1 项目能在几秒内构造恶意碰撞 - 2019 年研究人员伪造了一个有效的 SSL 证书(用 MD5 签名的)
MD5 现在能用吗? - ❌ 密码存储:禁用。用 bcrypt/Argon2 - ❌ 数字签名/证书:禁用。NIST 2010 年就警告停用 - ✅ 文件完整性校验:容易。大多数 Linux 发行版仍提供 md5sum,虽然已过时 - ⚠️ 去重哈希:可以,但精神上已不推荐。很多公司的数据库里仍有 MD5 作为文件快速去重用
实际情况:你不应该再选 MD5。但如果老系统已用 MD5 也别急着改(兼容性成本大),知道它的局限就行。
SHA-1:千禧年的标准,2017 年被 SHAttered
SHA-1(Secure Hash Algorithm-1)发布于 1995 年,输出 160 位(40 个十六进制字符),曾是安全哈希标准。
衰落历程: - 2005 年理论碰撞(改进的攻击算法) - 2017 年 SHAttered 事件:Google 和 CWI 联合公开演示了两个不同的 PDF 文件产生相同 SHA-1 哈希 - 计算耗时:6 个月 + 110 GPU 小时 - 成本:约 11 万美元 - 虽然成本很高,但证明了商用攻击已可行 - 2020 年 NIST 正式建议停用
SHA-1 现状: - ❌ Git 从 2017 年起逐步迁移 SHA-1 到 SHA-256(仍在过渡期) - ❌ 大多数浏览器 / 证书机构已禁止 SHA-1 签名证书 - ✅ 非安全场景仍广泛使用(Git 内部、版本控制标记)
总结:SHA-1 也别再选。Git 用户需要关注迁移时间表。
SHA-256 与 SHA-512:当前金牌方案
SHA-256 是 SHA-2 系列的一员(还有 SHA-224/SHA-384/SHA-512)。
特性对比: | 算法 | 输出位数 | 输出字符 | 安全强度 | 适用场景 | | --- | --- | --- | --- | --- | | SHA-256 | 256 bits | 64 字符 | 超强 | 文件校验、区块链、JSON Web Token | | SHA-512 | 512 bits | 128 字符 | 超强 | 需要更强安全裕度、数字签名 |
2026 年现状: - ✅ NIST 官方推荐 - ✅ 所有主流编程语言原生支持 - ✅ 证书、区块链(比特币)、Git、Docker 都采用 - ✅ 被认为在 2030-2050 年内仍然安全
实用建议:99% 场景选 SHA-256。它已成为事实标准。SHA-512 仅在需要超高安全裕度时用(如国防领域)。
SHA-3:新一代(可选)
SHA-3 是 2015 年发布的最新标准,采用 Keccak 海绵结构,与 SHA-2 算法原理完全不同。
特点: - 更高效的硬件实现 - 即使 SHA-2 被破解,SHA-3 的独立性保证系统安全(鸡蛋不放一个篮子) - 抗量子计算能力更强
现状: - ⚠️ 新项目可选择 SHA-3 - ⚠️ 但不紧迫(SHA-2 仍然安全且更广泛) - 📈 云存储(AWS S3)、高端密码学应用开始采用
实用建议:除非你做高端安全应用或量子安全规划,否则 SHA-256 足够。SHA-3 适合未来规划但现在选 SHA-2 不会错。
HMAC:带密钥的哈希,用于完整性与认证
HMAC(Hash-based Message Authentication Code)是在哈希基础上加一个密钥,产出认证码。
HMAC 工作流:
``
HMAC-SHA256(secret_key, message) = Hash(key XOR opad || Hash(key XOR ipad || message))
``
只有知道 secret_key 的人才能计算出正确的 HMAC。
应用场景: - API 认证:请求体 + timestamp + secret_key → HMAC,服务端同样计算验证。防止中间人篡改 - JWT 签名:header + payload + secret → HS256 (HMAC-SHA256) - Webhook 认证:GitHub 发 webhook 时会附加 X-Hub-Signature: sha256=...(用你的 webhook secret 计算)
HMAC vs 数字签名的区别: - HMAC:对称密钥(只有一个 secret),双方都能生成和验证,适合点对点通信 - 数字签名:非对称(私钥签名、公钥验证),发送方用私钥签,任何人用公钥验证,适合广播信息
下载文件校验:完整性与防篡改
- 网站发布文件 + SHA-256 哈希(通常放在同一页)
- 用户下载文件
- 用户本地计算该文件的 SHA-256
- 对比:若相同,文件完整且未被篡改
哪种情况下会失败? - 网络中断、下载不完整 → 哈希不同 - 中间人攻击、文件被篡改 → 哈希不同 - 但如果攻击者同时改文件和哈希(比如劫持网站),这方法失效
防范: - 哈希本身要从可信来源(如官网 HTTPS、PGP 签名)获取 - 网站用 SSL 证书保证来源真实 - 开源项目用 GPG 签名文件 + 发布者公钥,让任何人验证签名的真实性
本工具在浏览器内计算,无上传风险,适合离线验证。
性能对比与实测
在现代 CPU 上(Web Crypto API 或原生库): | 算法 | 1 MB 耗时 | 100 MB 耗时 | 相对速度 | | --- | --- | --- | --- | | MD5 | 0.5 ms | 50 ms | 最快(已报废) | | SHA-1 | 0.7 ms | 70 ms | 快(已淘汰) | | SHA-256 | 1.2 ms | 120 ms | 标准 | | SHA-512 | 1.0 ms | 100 ms | 稍快于 SHA-256(64 位 CPU) | | SHA-3 | 1.5 ms | 150 ms | 最慢(但仍可接受) |
结论:在当代硬件上,SHA-256 与 SHA-512 性能差异可忽略。安全性永远比速度重要。选 SHA-256 不会有性能问题。
Web Crypto API:浏览器内秒算哈希
Web Crypto API 是浏览器原生的加密库,提供 SHA-256/SHA-512/SHA-1(仅为兼容,不推荐)。
优势: - 完全在浏览器运行,无需上传服务器 - 性能比纯 JavaScript 快 10-100 倍(硬件加速) - 安全可信,是同一套标准库用于 HTTPS 证书验证
使用示例:
``javascript
const file = document.getElementById('file').files[0];
const buffer = await file.arrayBuffer();
const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
console.log('SHA-256:', hashHex); // 64 位十六进制字符
``
本工具就是基于 Web Crypto API,可秒级计算 GB 级文件的哈希(受浏览器内存限制)。
常见问题
MD5 现在还能用吗?
不能用于安全场景(密码、签名)。可用于非敏感的文件去重。新项目应该选 SHA-256。
SHA-256 输出的 64 个字符是什么?
256 bits ÷ 8 = 32 bytes,每个字节用 2 位十六进制表示,所以 32 × 2 = 64 个字符。
哈希相同的两个文件一定是同一个文件吗?
理论上有"碰撞"可能,但 SHA-256 的碰撞概率极低(计算上已不可行)。现实中可认为哈希相同 = 文件相同。
能从哈希值反推原始文件吗?
不能。哈希是单向函数,无法逆推。但可以用"彩虹表"(预先计算的哈希库)碰撞常见文件,所以不要用哈希储存密码。
HMAC 和数字签名哪个更安全?
都很安全,但用途不同。HMAC 适合双方通信,数字签名适合单向认证(发送方签名、公众验证)。