什么是 MD5 哈希,工作原理详解
MD5 简介
MD5(Message Digest Algorithm 5,消息摘要算法 5)是由 Ronald Rivest 在 1991 年设计的一种密码学哈希函数,属于 MD 系列算法。MD5 将任意长度的输入数据转换为固定长度(128 位,即 32 个十六进制字符)的哈希值,也称为"摘要"。
MD5("hello") = 5d41402abc4b2a76b9719d911017c592
MD5("Hello") = 8b1a9953c4611296a827abf8c47804d7
MD5("") = d41d8cd98f00b204e9800998ecf8427e
MD5("hello world") = 5eb63bbbe01eeed093cb22bb8f5acdc3
MD5 的核心特性
MD5 具备所有加密哈希函数的基本特性:
- **确定性:**相同的输入始终产生相同的哈希值
- **固定长度输出:**无论输入是 1 字节还是 1 GB,输出始终是 128 位(32 个十六进制字符)
- **雪崩效应:**输入的微小改变(哪怕只改一个字节)会导致输出完全不同
- **单向性:**理论上无法从哈希值反推原始输入(但已被彩虹表等方法破解)
- **计算速度快:**MD5 的计算速度非常快,这在现代安全场景中反而是一个弱点
MD5 的工作原理
MD5 处理输入数据的步骤:首先对输入进行填充(Padding),使其长度满足特定条件(通常是 512 位的倍数减 64 位);然后追加输入的原始长度(64 位);接着将数据分成 512 位的块;最后通过 4 轮 16 步的压缩函数(使用非线性函数、模加法、循环移位等操作)处理每个块,产生 128 位输出。
MD5 的安全问题
MD5 存在严重的安全弱点,不应再用于任何安全敏感场景:
- **碰撞攻击(Collision Attack):**2004 年,Wang 和 Yu 证明可以在普通计算机上找到 MD5 碰撞(两个不同输入产生相同哈希),2008 年研究者用此技术伪造了 SSL 证书
- **预像攻击(Preimage Attack):**对于较短的密码,MD5 哈希可以通过彩虹表快速反查
- **速度过快:**MD5 的高速度使得暴力破解非常容易,现代 GPU 每秒可以计算数百亿个 MD5 哈希
MD5 的合法使用场景
虽然 MD5 不再适合安全场景,但在非安全目的下仍然有效:
- **文件完整性校验:**验证文件在传输过程中是否被意外损坏(注意:不能防止恶意篡改)
- **文件去重:**快速比较大量文件是否内容相同(如数据库去重、图片库去重)
- **数据库索引/分桶:**将数据均匀分布到不同的存储分区(哈希分桶)
- **缓存键生成:**根据输入内容快速生成唯一的缓存标识符
MD5 输出格式
MD5 产生 128 位(16 字节)的哈希值,通常表示为 32 个十六进制字符(小写)。有时也会看到 Base64 编码的 MD5 输出(22 个字符加 ==),这在 HTTP 内容摘要头(Content-MD5)中使用:
/* Standard hex format (32 chars) */
5d41402abc4b2a76b9719d911017c592
/* Base64 format (24 chars) */
XUFAKrxLKna5cZ2REBfFkg==
/* Upper case hex (also valid) */
5D41402ABC4B2A76B9719D911017C592
在各编程语言中计算 MD5
// JavaScript (Node.js)
const crypto = require('crypto');
const hash = crypto.createHash('md5').update('hello').digest('hex');
// '5d41402abc4b2a76b9719d911017c592'
// Python
import hashlib
hash = hashlib.md5(b'hello').hexdigest()
# '5d41402abc4b2a76b9719d911017c592'
// PHP
$hash = md5('hello');
// '5d41402abc4b2a76b9719d911017c592'
// Go
import "crypto/md5"; import "fmt"
hash := fmt.Sprintf("%x", md5.Sum([]byte("hello")))
立即免费使用相关工具
免费使用 →