MD5、SHA-1、SHA-256 哈希到底是什么:用途、安全边界与加盐
讲清 MD5、SHA-1、SHA-256 三种哈希的区别和用途,文件校验怎么做,为什么 MD5 不能存密码,单向不可逆是什么意思,以及加盐为什么不可省。
MD5、SHA-1、SHA-256 哈希到底是什么
哈希是一类把任意长度的数据,压成一段固定长度指纹的函数。你喂进去 3 个字节还是 4 GB 的镜像文件,出来的摘要长度都一样。MD5 输出 128 位(32 位十六进制),SHA-256 输出 256 位(64 位十六进制),SHA-1 介于两者之间,是 160 位。长度固定、同样的输入永远得到同样的结果,这两点决定了它的全部用途。
很多人第一次接触哈希,是在某个下载页面看到一串 sha256: 3b1f... 的字符。它不是加密,不是压缩,而是给文件留的一枚指纹。下面把三种常见算法和它们的安全边界讲清楚。
一个具体例子:同一个字符串的三种摘要
抽象的定义不如一个真实例子。把字符串 abc(就这 3 个字节,不带换行)分别算一遍:
- MD5:
900150983cd24fb0d6963f7d28e17f72 - SHA-1:
a9993e364706816aba3e25717850c26c9cd0d89d - SHA-256:
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
注意三串长度不同,这正是位数差异的直观体现:32 位、40 位、64 位十六进制。你可以在 /zh/t/md5-sha-hash/ 里粘 abc 自己验一遍,五种摘要会一次性全部列出。这里有个常见的坑:命令行 echo "abc" | md5sum 算出来的值对不上,因为 echo 默认补了一个换行,实际算的是 abc\n 这 4 个字节。想精确到字节,用 printf '%s' abc | md5sum。
单向不可逆:哈希不是加密
哈希最关键的性质是单向。从 abc 算出 SHA-256 很快,但拿着那 64 位摘要反推回 abc,在数学上没有捷径,只能一个一个去猜然后比对。加密是双向的,有密钥就能解回明文;哈希没有解密这回事,它根本不保存原文的任何可还原信息。
正因为不可逆,哈希才适合做指纹和校验:你不需要知道原文是什么,只需要确认两份数据的指纹一不一样。但也正因为它本质是"快速猜测可比对",密码场景里这个"快"反而成了致命弱点,后面会说到。
它能做什么:文件校验与去重
哈希最日常的两个用途,一个是文件完整性校验,一个是去重。
校验的逻辑很朴素:发布者把文件的 SHA-256 公布在官网,你本地下载完跑 shasum -a 256 ubuntu.iso,把两串 64 位十六进制逐位对一遍。一模一样,说明文件在传输中没被截断、没被篡改;差一个字符,重新下载。这里必须整串全比,只看前几位是危险的:a1b2... 和 a1b3... 看着像,其实是完全不同的两个文件。
去重则是利用"同输入同输出":给 500 条用户投稿各算一个 MD5,把 32 位摘要当集合的键,两条内容完全一样的片段必然撞到同一个 MD5,留一份丢其余。整个过程只存 16 字节指纹,原文一个字节都不落地。去重不涉及对抗安全,MD5 在这种场景里够用且快。
为什么 MD5 不能用于密码
MD5 早在 2004 年就被证明存在碰撞攻击,即可以构造出两段不同的数据却得到相同的 MD5 摘要。这意味着它的"指纹唯一性"在被恶意攻击时不再成立。SHA-1 也在 2017 年被 Google 用 SHAttered 攻击实际碰撞掉,如今同样不建议用于任何安全场景。
但密码场景里,MD5 最大的问题还不止碰撞。它太快了。现代显卡每秒能算几十亿次 MD5,加上彩虹表(预先算好的"明文到摘要"对照表),一个不加盐的 MD5 密码摘要往往几秒就被还原。说我以前接手过一个老系统,用户表里整列都是裸 MD5,导出来跑了个开源彩虹表,十分钟内还原出大半常见弱密码,那一刻才真切体会到"快"在这里是反作用。
结论很直接:密码不要用 MD5,也不要用任何为速度设计的通用哈希。该用专门的密码哈希,比如 bcrypt 或 Argon2,它们故意算得慢,还内置加盐。需要的话可以直接用 /zh/t/bcrypt-generator/ 生成 bcrypt 摘要看看它长什么样。
加盐:为什么不可省
加盐,就是给每个用户的密码拼一段随机字符串再去做哈希。它解决的是"相同密码产生相同摘要"这个泄密点。不加盐时,两个用户都用 123456,摘要完全一样,攻击者一眼就能看出哪些人密码相同,彩虹表也能批量命中。加了各不相同的盐之后,同样的 123456 在每个用户那里摘要都不同,预先算好的彩虹表整个失效,攻击者只能逐个用户单独爆破,成本直接上几个数量级。
bcrypt 和 Argon2 会自动把盐和迭代参数一起存进摘要字符串,你不用手动管。但概念要清楚:盐不是机密,可以明文存,它的作用是打散,不是隐藏。
哈希这套东西,记住三句话就够用:校验和指纹放心用 SHA-256,旧系统里的 MD5 和 SHA-1 该退役了,密码这条路只走 bcrypt 或 Argon2 并且必须加盐。
Made by Toolora · Updated 2026-06-13