核心答案:哈希是把任意长度数据映射为定长指纹的单向函数——MD5 出 32 位十六进制、SHA-256 出 64 位。MD5/SHA-1 已被破解只能用于校验文件完整性;存密码必须用 bcrypt/scrypt/Argon2 这类慢哈希加盐。

哈希基础

哈希函数三大特性:

  1. 单向性:从哈希值无法反推原文
  2. 雪崩效应:输入改 1 位,输出天翻地覆
  3. 定长输出:1 字节和 1 GB 文件哈希值一样长

"hello" 的 SHA-256:2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

常见算法对照表

算法输出长度状态可用场景
MD5128 位/32 hex❌ 已破解仅文件完整性校验
SHA-1160 位/40 hex❌ 已破解(2017 谷歌碰撞)同上,逐步淘汰
SHA-256256 位/64 hex✅ 安全签名、区块链、校验
SHA-512512 位✅ 安全高安全场景
bcrypt60 字符✅ 密码专用密码存储
Argon2可变✅ 密码专用(2015 竞赛冠军)密码存储首选

典型用途

场景用法
文件校验下载页给出 SHA-256,本地算一遍比对
密码存储bcrypt(密码+随机盐) 存库
数据指纹Git 用 SHA-1 标识每次提交
数字签名先哈希再私钥加密
区块链区块头哈希串联成链

MD5 为什么不安全

  • 2004 年王小云团队实现理论碰撞,2012 年 Flame 病毒利用 MD5 碰撞伪造微软签名
  • 现代 GPU 每秒可算数百亿次 MD5,彩虹表全覆盖常见密码
  • "碰撞"意味着两个不同文件可以有相同 MD5——校验防篡改已不可信
  • 现状定位:只能用于"非恶意场景"的完整性检查(如传输误码)

密码存储正确姿势

做法评级
明文存储灾难
MD5(密码)灾难(彩虹表秒破)
SHA-256(密码)差(太快,GPU 暴力破解友好)
SHA-256(密码+盐)一般(仍太快)
bcrypt(密码+盐, cost≥10)
Argon2id(密码+盐)最佳

慢哈希的核心:故意让单次计算耗时 100ms+,攻击者每秒只能试 10 个密码。

常见误区

  1. 哈希=加密:加密可逆(有密钥能解密),哈希不可逆。说"MD5 加密"是术语错误。
  2. 哈希后再 Base64 就安全:编码不改变安全性,攻击者解码后再破哈希。
  3. 自己发明哈希算法:密码学第一铁律——不要自造轮子,用经公开审查的标准算法。
  4. 盐可以复用:每个密码必须用独立随机盐,否则彩虹表依然有效。

用[哈希计算器](/c/dev/hash)在线计算文本的 MD5/SHA-1/SHA-256。