MD5

一句话说明

MD5 的价值现在主要不在“安全”,而在“快速生成一个固定长度的历史兼容指纹”。

先说结论

MD5 可以把任意长度输入映射成固定的 128 bit 摘要,通常写成 32 位十六进制字符串。

MD5("hello") = 5d41402abc4b2a76b9719d911017c592

但更重要的结论是:

安全结论

MD5 已经不适合用于密码存储、数字签名、证书、防篡改校验等依赖抗碰撞能力的场景。

它还能做什么

可以谨慎用于:

  • 非安全用途的文件指纹
  • 缓存 key
  • 数据去重的第一层快速筛选
  • 老系统兼容

不该用于:

  • 密码存储
  • 签名校验
  • 安全完整性验证
  • 任何需要强抗碰撞的场景

Go 代码:字符串 MD5

func MD5Hex(text string) string {
    sum := md5.Sum([]byte(text))
    return hex.EncodeToString(sum[:])
}

Go 代码:文件 MD5

func FileMD5(path string) (string, error) {
    file, err := os.Open(path)
    if err != nil {
        return "", err
    }
    defer file.Close()
 
    h := md5.New()
    if _, err := io.Copy(h, file); err != nil {
        return "", err
    }
    return hex.EncodeToString(h.Sum(nil)), nil
}

Go 代码:完整示例

func main() {
    fmt.Println(MD5Hex("hello"))
 
    hash, err := FileMD5("demo.txt")
    if err != nil {
        panic(err)
    }
    fmt.Println(hash)
}

为什么它不等于“加密”

MD5 是哈希,不是加密。

  • 加密强调可逆
  • 哈希强调压缩映射和快速摘要

所以“MD5 解密”这种说法本身就不准确。
网上所谓“解密 MD5”,本质上通常是撞库、字典表或彩虹表匹配。

为什么加盐也不够

给 MD5 加盐,确实能让预计算攻击更难。
但它解决不了两个根问题:

  • MD5 太快,暴力枚举成本低
  • MD5 抗碰撞能力已经不够

所以密码存储应该直接上:

  • Argon2
  • bcrypt
  • scrypt
  • PBKDF2

和 SHA-256 的区别

算法输出长度当前安全性常见用途
MD5128 bit不安全历史兼容、非安全指纹
SHA-1160 bit不推荐历史兼容
SHA-256256 bit当前常用完整性校验、签名相关

什么时候还会碰到它

  • 老接口签名协议
  • 下载页里的文件摘要
  • 历史系统数据库字段
  • 某些缓存 / 去重脚本

也就是说,你现在更多是“要会识别和兼容它”,而不是“主动选它做安全方案”。

易错点

关于 MD5 的常见误区

  • MD5 不是加密算法。
  • 两个文件 MD5 相同,不代表在密码学意义上绝对安全地“相同”。
  • 加盐 MD5 也不适合作为现代密码存储方案。

相关笔记


返回:数据结构