哈希函数是什么
哈希把任意长度的输入映射成固定长度的摘要,且不可逆:同一输入永远得到同一结果,输入变化一点点输出就完全不同。它用于校验完整性、做数字签名的摘要、给口令加盐后存储。要点是哈希不等于加密——它没法「解密」,也不提供机密性;用于防篡改时要用 HMAC 或签名,而不是裸哈希。
基本信息
| 输出长度 | MD5 128 位、SHA-1 160 位、SHA-256 256 位、SHA-512 512 位 |
|---|---|
| 性质 | 单向、确定性、抗碰撞(强度随算法而异) |
| 应用 | 完整性校验、签名摘要、口令存储、去重指纹 |
| 口令存储 | 需加盐并迭代,用 bcrypt/scrypt/Argon2 |
| 规范 | FIPS 180-4(SHA-2)、FIPS 202(SHA-3) |
| 命令行 | sha256sum、openssl dgst |
典型使用场景
- 校验下载文件是否损坏或被篡改:与官方公布的摘要比对
- 数字签名与证书:先对内容做摘要再签名,提高效率
- 口令存储:加盐慢哈希,防止彩虹表与批量爆破
- 内容寻址与去重:用摘要作为唯一标识(如 git 对象、制品仓库)
- 数据同步与备份校验:快速比对两端是否一致
常用命令
常用命令
sha256sum file.iso # 计算摘要
sha256sum -c checksums.txt # 按清单批量校验
openssl dgst -sha256 file.iso # 用 openssl 计算
openssl dgst -sha256 -hmac "$SECRET" payload.bin # 带密钥的 HMAC,防篡改
# 口令存储不要用裸哈希,正确做法是加盐慢哈希(伪代码)
# hash = argon2id(password, salt=random(16), time=3, memory=65536)算法现状
| 算法 | 输出 | 现状 |
|---|---|---|
| MD5 | 128 位 | 已能构造碰撞,禁止用于安全场景 |
| SHA-1 | 160 位 | 已有实用碰撞案例,全面弃用 |
| SHA-256 | 256 位 | 当前通用安全选择 |
| SHA-384/512 | 更长摘要 | 高强度场景与 SHA-512 系签名配合 |
| SHA-3 | Keccak 结构 | 备选标准,抗长度扩展攻击 |
| HMAC-SHA256 | 带密钥摘要 | 消息认证的正确姿势 |
裸哈希有个固有弱点:拿到摘要的人可以穷举猜测原文(口令尤其明显),也能对「摘要 + 追加内容」构造长度扩展攻击。前者靠加盐与慢哈希解决,后者靠 HMAC 或 SHA-3 的结构解决。
把 SHA-256 摘要当作防篡改证据要谨慎:攻击者若能同时改写文件与摘要,校验依然会通过。真正防篡改需要 HMAC(共享密钥)或数字签名(非对称密钥),并保证校验值的分发渠道独立可信。