前言

哈希算法在安全领域应用广泛,但不同场景需要不同算法。本文对比常用算法的特点。

什么是哈希函数

哈希函数将任意长度的输入转换为固定长度的输出,具有以下特性:

  • 确定性: 相同输入永远产生相同输出
  • 快速计算: 计算效率高
  • 抗原像性: 难以从哈希值反推原始输入
  • 抗碰撞性: 难以找到两个不同输入产生相同哈希值

常用算法对比

算法 输出长度 安全性 典型用途
MD5 128 bit ❌ 已破解 文件校验(非安全场景)
SHA-1 160 bit ❌ 已破解 Git(遗留兼容)
SHA-256 256 bit ✅ 安全 数字签名、TLS
bcrypt 192 bit ✅ 安全 密码存储

为什么密码存储不能用 SHA-256?

SHA-256 设计目标是快速计算,这恰恰是密码存储的大忌:

1
2
3
# SHA-256 计算极快
time echo "password" | openssl dgst -sha256
# 实际耗时:毫秒级

攻击者可以每秒尝试数十亿次密码,暴力破解轻而易举。

bcrypt:专为密码设计

bcrypt 有三个关键特性:

  1. 计算慢: 默认耗时约 100ms
  2. 可调成本: 通过 cost 参数增加计算量
  3. 内置盐值: 无需单独存储 salt
1
2
3
4
5
6
7
8
# Python 示例
import bcrypt

# 哈希密码(cost=12)
hashed = bcrypt.hashpw(b"password", bcrypt.gensalt(rounds=12))

# 验证密码
bcrypt.checkpw(b"password", hashed)  # True

计算速度对比

算法 每秒计算次数
MD5 ~10 亿
SHA-256 ~5 亿
bcrypt (cost=12) ~10

bcrypt 慢 8 个数量级,这正是我们需要的。

实际应用建议

  • 文件完整性校验: SHA-256
  • 数字签名: SHA-256 或 SHA-384
  • 密码存储: bcrypt 或 Argon2
  • 遗留系统校验: MD5(仅当不需要安全保证时)

小结

哈希算法选择取决于场景:快速算法适合签名和校验,慢速算法适合密码存储。存储密码务必使用 bcrypt 或 Argon2。