哈希与 HMAC 在线计算
一次算出 MD5、SHA-1、SHA-256、SHA-384、SHA-512 五种结果(十六进制 + Base64),支持任意文件的哈希校验、HMAC 签名与哈希比对
文本哈希
哈希是单向的:同样的内容永远得到同样的值,但从哈希值推不回原文。所以「计算哈希」不等于「加密」,不要用它保存密码。
输入文本后点「计算哈希」,这里会同时列出五种算法的结果。
哈希比对(核对下载文件 / 校验值)
比对的是「文本模式」或「文件模式」最近一次算出来的结果(如果你在别的工具里算过,直接把那个值粘进来也能用)。这个动作专治一件事:下载下来的文件到底有没有损坏——官网给的校验值和本地算出来不一致,说明文件在传输或解压过程中就被改动了。
哈希能做什么、不能做什么
哈希是把任意长度的内容压成固定长度的「指纹」。不管你输入一个字符还是一部电影,SHA-256 永远输出 256 位(32 字节,十六进制 64 个字符),MD5 永远输出 128 位(32 个字符)。它的用途只有两类:一是校验完整性——文件在下载、拷贝、解压、上传过程中有没有被改动哪怕 1 个比特,哈希值都会完全不同,所以软件官网、镜像站、网盘都会同时给出文件的 MD5 或 SHA-256;二是当作内容的唯一标识——去重、缓存键、Git 的提交号、区块链的区块头,都用哈希值指代内容本身。它不能用来「加密」:哈希是单向的,没有密钥也没有逆运算,把哈希值给出去不等于泄露原文(这正是密码库存密码摘要的原理,但存密码必须用专门设计的慢哈希,不能用这里的通用哈希)。
为什么 MD5 和 SHA-1 已经不适合做安全用途。它们不是「被算出来了」,而是碰撞被实际构造出来了:碰撞指的是找出两段内容不同、哈希值却完全相同的文件。MD5 的碰撞早在 2004 年就被王小云团队从理论上攻破,2008 年出现了能伪造 CA 证书的实用攻击,如今普通电脑几秒就能生成一对碰撞文件;SHA-1 的第一个公开碰撞(SHAttered)在 2017 年由 Google 与 CWI 公布,两个内容不同但 SHA-1 相同的 PDF 摆在眼前,2020 年又出现了成本更低的选前缀碰撞。碰撞一旦可用,签名、证书、校验就都能被伪造:攻击者可以让一份「无害文件」和一份「恶意文件」拥有同一个 MD5,先让你签无害的那份,再把恶意的那份拿去冒充。所以:做校验完整性、兼容老系统,用 MD5 / SHA-1 没关系;做数字签名、证书、口令、防篡改,必须用 SHA-256 及以上。本页把五种算法一次列全,并在 MD5 与 SHA-1 旁标出「不适合安全用途」,就是为了不让「能算出结果」被误读成「可以用来签名」。
为什么同样的内容必须得到同样的哈希值,而文件哈希要连换行都不能改。哈希算法完全按字节算:一个字节的差异会被雪崩效应放大到结果的一半比特都翻转,所以「看着一样」的文本与文件可能哈希完全不同。最常见的坑有三个:Windows 记事本存的换行是 \r\n(CRLF),Linux 与 macOS 是 \n(LF),同一段文字在两种系统里哈希就不一样;文本编辑器自动在文末补一个换行,也会让哈希变化;压缩包重新打包一次(哪怕内容一样)哈希也会变。所以核对文件哈希时,要比对的是同一个文件,不要拿「我复制出来的文本」去和「原文文件的哈希」比。本页文本模式按 UTF-8 编码计算(中文一个字 3 字节、emoji 通常是 4 字节),文件模式按文件的原始字节计算,两者口径一致,可以互相核对。
文件校验的典型场景。① 下载系统镜像或开发工具后,用官网给出的 SHA-256 对照本地哈希,确认没有被镜像站替换或传输损坏;② 从手机往电脑传大文件,两边各算一次 MD5,值一样才敢删掉源文件;③ 团队交接数据包时附一份哈希清单,对方逐个核对,比「应该没问题」可靠得多;④ 排查「文件被谁改过」——把现在的哈希和历史记录一比就知道有没有被动过;⑤ 兼容场景:有些老系统、老接口、老设备只认 MD5,这时仍然得算 MD5,只是要清楚它只保证完整性、不保证抗抵赖。本页的比对区会直接告诉你「匹配」还是「不匹配(差异在第 N 位)」,比肉眼逐字符比对可靠——哈希值恰恰是最不适合肉眼比对的东西,一眼扫过去 64 个十六进制字符,看漏一位的概率非常高。
HMAC 与普通哈希的区别。普通哈希没有密钥:任何人拿到文件都能算出同一个值,所以它能证明「内容没变」,不能证明「这个值是谁给的」,也无法阻止别人改完内容再重算一个哈希附上。HMAC(Hash-based Message Authentication Code)把密钥和消息一起参与运算,输出一个只有知道密钥的人才能生成的签名:接口把参数按约定顺序拼好、用自己的密钥算 HMAC,服务端收到后用同一把密钥重算,两边一致才认——这样即使请求经过不可信的链路,别人既改不了参数(改了签名就不对),也造不出新签名(没有密钥)。所以「校验文件是否损坏」用普通哈希就够了,「证明这个请求来自持有密钥的一方」才需要 HMAC。本页的 HMAC 走浏览器内置接口,密钥支持按文本或按十六进制字节解读。
为什么这些计算必须在你自己的浏览器里完成,而不是「上传到服务器算好再给你」。哈希的输入往往比结果敏感得多:你粘进来的可能是待发布的合同正文、配置文件、含密钥的脚本片段,或者是整份内部资料文件;HMAC 模式下你还得填一个密钥——任何声称「在线 HMAC 计算」却把密钥 POST 到自己服务器的工具,等于让你把密钥交出去。本页的做法是把计算全部留在本地:SHA 系列用浏览器内置的加密接口(crypto.subtle.digest / crypto.subtle.sign),MD5 用随页面下发的小库(js-md5,MIT 许可),文件用浏览器的本地文件读取接口读进内存。整页不发任何上传请求,你可以打开开发者工具的 Network 面板亲自验证:把文件拖进来算一遍,看有没有新的请求出现。页面也不写 localStorage、不写 cookie、不把你的输入写进网址——你算过什么,服务器一无所知。另外请注意一个技术前提:浏览器只在安全上下文(https 或 localhost / 127.0.0.1)里提供 SHA 系列所需的加密接口,如果你通过 http 访问本页,SHA 系列会被浏览器禁用、页面会明确提示,而 MD5 不依赖该接口,仍然可用。
常见问题
要分场景。做完整性校验(下载完对一下、传输后核对)、兼容只认 MD5 的老系统,它还能用,本页也照常提供。但做数字签名、证书、密码存储、防篡改就不行了:MD5 的碰撞已经被实际构造出来,攻击者可以做出两个内容不同、MD5 相同的文件。SHA-1 同样已被攻破(2017 年的 SHAttered 公开碰撞)。需要抗碰撞时请用 SHA-256 及以上,本页已把五种算法一次列全,方便你按场景取用。
不会。文件哈希是在你的浏览器里算的:页面用本地文件读取接口把文件读进内存,再交给浏览器内置的加密接口(SHA 系列)或随页面下发的小库(MD5)计算,全程没有网络请求。你可以自己验证:打开开发者工具的 Network 面板,把文件拖进页面算一遍,不会出现任何新的上传请求。也正因为不上传,本页没有文件大小限制,但几百 MB 以上的文件会因为读入内存而明显变慢。
先确认三件事:① 是不是同一个文件——解压、重新打包、用编辑器打开后保存过都会改变字节;② 是不是同一套换行——Windows 的 CRLF 与 Linux/macOS 的 LF 是不同的字节,文本文件最容易在这里翻车;③ 算法是不是同一个——MD5 与 SHA-256 的值长度都不同,别拿 MD5 去对 SHA-1。如果这三条都对得上还不同,那基本可以认定文件在传输或存储过程中被改动了,建议重新下载并比对官方公布的校验值。
SHA-1/256/384/512 用的是浏览器内置的 crypto.subtle 加密接口,浏览器只允许在安全上下文(https 或 localhost / 127.0.0.1)里使用它;通过 http 打开页面时该接口不存在,SHA 系列无法计算。这时 MD5 仍然可用(它不依赖这个接口),你也可以改用 https 访问本站,或把整页保存到本地打开来算。页面遇到这种情况会给出明确提示,不会白屏、也不会抛未捕获的错误。
密钥在计算机里本来就是一串字节,用文本表示只是一种约定。勾上「密钥是十六进制」后,页面会把 6b6579 这样的字符串按每两个字符一个字节解析成 3 个字节(0x6B 0x65 0x79),而不是当成 6 个字符的文本。很多接口文档给的密钥就是十六进制串(尤其是二进制密钥),这时必须勾选;如果文档给的是「secret」这类可读字符串,就不要勾。填了奇数个字符或出现非十六进制字符,页面会直接拒绝并提示,而不是悄悄按文本算一个错误的结果。