如何生成 MD5、SHA-256 等哈希

· 9 分钟阅读

哈希把任何输入(一个密码、一个文件、一条消息)转换为固定长度的字符串。同一输入总产生同一哈希,而即使是输入中最微小的变化也会产生完全不同的哈希。这使哈希成为完整性验证、密码存储、数字签名、区块链证明以及现代计算十几种其他基石的必备。选对算法、知道为什么有些已被攻破、并辨认出滥用哈希的模式,会让一个五秒钟的小工具变成可以安全立足其上的基础。

哈希函数简史

作为编程概念的哈希比密码学早了数十年,数据结构里的哈希表使用 CRC、FNV 等简单函数把键散布到桶里。设计成不可逆且抗碰撞的密码学哈希,出现于 1980 年代末:Ron Rivest 的 MD4(1990)与 MD5(1991)。MD5 成为事实标准长达二十年,直到实用碰撞使其在安全场景中不再可用。

NIST 的 SHA-0(1993)几乎立即被撤回,由 SHA-1(1995)替代。SHA-1 撑得更久,但分阶段被攻破:2005 年的理论攻击、2009 年具备实际意义的证书伪造场景、2017 年 Google 的 SHAttered 演示,两份不同的 PDF 拥有相同的 SHA-1 哈希。2001 年发布的 SHA-2 家族(SHA-224、SHA-256、SHA-384、SHA-512)被设计为更长期的替代者,至今仍然安全。SHA-3(Keccak,2015 年标准化)在结构上不同,目的是在 SHA-2 倒下时提供后备。

与此并行,面向密码的哈希则单独演化。纯 MD5 或 SHA-1 用于密码存储太快,于是 bcrypt(1999)、scrypt(2009)与 Argon2(2015,密码哈希竞赛胜出者)添加了刻意的慢与内存难度,把暴力破解的成本提升了数个数量级。对密码合适的哈希,从来都不是对文件校验合适的那个。

哈希如何工作

哈希函数接收任意大小的输入,产出固定大小的输出:

输入SHA-256 哈希(前 16 个字符)
hello2cf24dba5fb0a30e...
Hello185f8db32271fe25...
hello!ce06092fb948d9ff...

注意,把一个字符从小写 h 改为大写 H,或者添加一个字符,哈希就完全变了。这叫雪崩效应,正是它让哈希善于捕捉任何细小变化。

在内部,现代哈希函数把输入切成固定大小的块(SHA-256 是 64 字节,SHA-512 是 128 字节),让每个块通过压缩函数,并把状态向前链接。输出是最后一块混入后的最终状态。由于链依赖于每一个字节,没有捷径能让攻击者在不重写整个哈希的情况下修改输入。

一个好的密码学哈希具备三个安全性质:抗原像(你找不到能产生给定哈希的输入)、抗第二原像(给定一个输入,你找不到另一个产生同一哈希的输入)以及抗碰撞(你找不到任意两个不同的输入产生同一哈希)。MD5 三者全失;SHA-1 失去抗碰撞;SHA-2 与 SHA-3 仍保有三者。

常见哈希算法

算法输出位数输出长度状态用途
MD512832 个十六进制字符已破(不安全)遗留校验、非安全用途
SHA-116040 个十六进制字符已破(不安全)仅限遗留系统
SHA-22422456 个十六进制字符安全(小众)建议优先 SHA-256
SHA-25625664 个十六进制字符安全文件完整性、数字签名
SHA-38438496 个十六进制字符安全TLS 1.3 套件
SHA-512512128 个十六进制字符安全高安全应用,64 位性能
SHA3-25625664 个十六进制字符安全SHA-256 的前瞻替代
BLAKE2b / BLAKE3256 或 512可变安全且非常快rsync、restic、批量哈希
HMAC-SHA25625664 个十六进制字符安全API 请求签名
bcrypt18460 个字符(自定义)对密码安全密码存储
Argon2id可配置可变密码最佳现代密码存储
CRC32328 个十六进制字符仅错误检测不是安全哈希

大多数通用用途下,SHA-256 是当前标准。MD5 与 SHA-1 仅应在必须与需要它们的遗留系统交互时使用,绝不用作安全边界。对密码,使用 bcrypt 或 Argon2id,而不是原始 SHA-256。

如何生成哈希

  1. 选择算法:在下拉框中选 MD5、SHA-1、SHA-256、SHA-384 或 SHA-512。除非有特定原因选其它,否则用 SHA-256。
  2. 输入文本或上传文件:在输入框里键入或粘贴文本,或拖入一个文件。该工具用 Web Crypto API 完全在你的浏览器中运行。
  3. 复制哈希:结果是十六进制字符串,可用于验证、存储或比较。许多工具还提供 base64 编码以紧凑存储。
  4. 需要时比较:把已发布哈希粘到生成哈希旁,让工具标出第一个不同字符。肉眼比对 64 字符字符串容易出错。

实际用途

文件完整性验证:下载一个文件,把其哈希与发布者的官方哈希对比。若一致,文件就是真实且未损坏的。这是日常哈希生成最常见的用例,Linux 上每一次 sha256sum 的背后,以及每一个软件下载页上的校验和页面,都是这一流程。

密码存储,应用存储的是密码的哈希而非密码本身。当你登录时,你的输入会被哈希并与已存哈希对比。关键点在于算法必须故意放慢(bcrypt、Argon2),以使盗走哈希文件的攻击者无法在合理时间内暴力破解。

数据去重:存储系统和备份工具会对数据块(常是几兆字节)进行哈希,并把哈希用作键。具有相同哈希的两块被视作相同,因此第二次出现仅存指针。restic、borg 以及许多云备份服务都依赖此原理。

数字签名:数字签名是被私钥加密的哈希。验证者对文档哈希、用公钥解开签名,核对两者是否一致。这既证明文档没有改动,也证明签名者批准了正是这一版。

用于 API 安全的 HMAC:HMAC 将哈希函数与密钥结合,产出一个任何持有相同密钥者都能验证的标签。Webhooks、AWS 请求签名以及许多内部 RPC 都用 HMAC-SHA256,以便接收方知道请求确实来自可信来源。

区块链与 Merkle 树:加密货币、内容寻址存储(IPFS)和 Git 都使用哈希树,以一个根哈希对庞大数据集做出承诺。在树中任何地方改动一个字节,根哈希都会变,这正是数据具备防篡改性的性质。

缓存键:缓存系统对请求 URL 或查询参数做哈希,生成紧凑的查找键。这里常见 CRC 与 SipHash,因为它们更看重速度而非密码学保证。

哈希 vs HMAC vs 数字签名

由于三者都输出形状相似的十六进制字符串,常被混淆。

概念输入验证什么常见用途
哈希数据自哈希计算以来数据未变校验和、内容寻址
HMAC数据 + 共享密钥数据未变 且 由持有密钥者创建API 请求签名、webhooks
数字签名数据 + 私钥数据未变 且 由特定密钥签署TLS 证书、软件签名
加密数据 + 密钥(任意)数据在传输中保持机密保密性(不只是完整性)

纯哈希并不能证明谁创建了它。HMAC 证明发送方掌握共享密钥。签名进一步在无需共享密钥的情况下识别签名者。选择能解决你实际问题的最弱工具。

常见陷阱

替代工具与库

浏览器哈希生成器是一次性哈希最快的路径。对于重复使用或脚本化,命令行与语言库接手。

工具平台优势注意
网页哈希生成器浏览器即时、免安装、无上传一次一个输入
sha256summd5sumLinux可脚本、GNU coreutils--check 读取 SHA256SUMS 文件
shasum -a 256macOS、BSD系统自带与 Linux 上二进制名不同
Get-FileHashWindows PowerShellWindows 上一等公民输出格式与 sha256sum 不同
openssl dgst -sha256跨平台如果你已经有 OpenSSL比专用工具慢
b3sum / BLAKE3 CLI跨平台数 GB/s 吞吐较新,不那么普及
Python hashlibPython内置,涵盖所有主流算法请使用字节输入
Node cryptoNode.js内置,API 与 Python 类似大文件请用流式
Web Crypto subtle.digest浏览器 JS原生、快、无依赖仅异步 API
HashiCorp Vault / KMS用于 HMAC 与签名的集中式密钥管理厂商锁定

对于密码,语言生态请区别对待:使用 bcryptargon2-cffipasslib 或你平台推荐的适配器,不要自己手写 SHA 循环。

隐私与哈希生成器

哈希生成器完全在你的浏览器中运行。你键入的文本会通过 Web Crypto SubtleCrypto 接口在内存中被哈希,你选择的任何文件都通过 FileReader API 流式传入,而不上传。没有记录哪些输入被哈希的日志,没有关于哪些算法流行的分析,也没人能重建你在验证什么。哈希本身常常是敏感材料的摘要,密码、内部文件、私钥,正是你绝不该粘进陌生人网页表单的那类数据。把工作放在客户端,可以把输入留在你的机器上,本该在那里。对于像生成校验和这样的日常任务,默认的隐私应当是:任何东西都不离开页面、不被存储、不被分享。

常见问题

MD5、SHA-1 和 SHA-256 有什么区别?

MD5 生成 128 位哈希(32 个十六进制字符),SHA-1 生成 160 位(40 个字符),SHA-256 生成 256 位(64 个字符)。MD5 和 SHA-1 被认为在密码学上已被攻破。SHA-256 目前是安全的,推荐用于完整性验证和安全。

可以反向破解哈希以找回原始数据吗?

不可以。哈希函数按设计是单向的。您无法从数学上将哈希反向为其输入。不过,常用密码可以在预计算表(彩虹表)中查找,这就是为什么在哈希前为密码加盐很重要。

什么是 HMAC?

HMAC(Hash-based Message Authentication Code)将哈希函数与密钥结合。它同时验证数据的完整性和真实性 · 证明它未被篡改且由知道密钥的人生成。

我的数据会发送到服务器吗?

不会。所有哈希都通过 Web Crypto API 在您的浏览器中运行。您的文本和文件从不离开您的设备。

Why should I never use MD5 or SHA-1 for password storage even with a salt?

Both algorithms are extremely fast, which is the opposite of what you want for passwords. An attacker with a stolen hash file can try billions of guesses per second on a GPU. Password-hashing functions like bcrypt, scrypt, and Argon2 are deliberately slow and memory-hard, which forces attackers to spend orders of magnitude more time per guess.

When should I use SHA-512 instead of SHA-256?

On 64-bit CPUs, SHA-512 is often slightly faster than SHA-256 because its inner state and word size are tuned to 64-bit operations. Use SHA-512 when you want a longer digest (128 hex characters) for collision resistance margin, or when you are already in a SHA-512 ecosystem (TLS 1.3 with certain cipher suites, some HMAC implementations).