🌸
💫
跳转到内容
非官方中文文档 彩虹工具箱

MD5 加密

专业的 MD5 哈希计算工具,支持文本、文件 MD5 值计算,提供多种高级功能。

MD5(Message-Digest Algorithm 5)是一种广泛使用的密码散列函数,产生 128 位(16 字节)的哈希值,通常表示为 32 位十六进制数。

  • 固定长度 - 无论输入多长,输出都是 32 位十六进制字符串
  • 单向性 - 无法从哈希值反推出原始数据
  • 抗修改 - 输入微小变化,输出完全不同
  • 快速计算 - 计算速度快
  • 🔐 密码存储 - 存储用户密码的哈希值
  • 📁 文件校验 - 验证文件完整性
  • 🔍 数据去重 - 快速判断数据是否相同
  • 🏷️ 数字签名 - 生成数据唯一标识
  1. 在输入框中输入文本:
Hello World
  1. 点击「计算 MD5」按钮
  2. 获取结果:
b10a8db164e0754105b7a99be72e3fe5
  1. 点击「选择文件」或拖拽文件到上传区域
  2. 等待计算完成
  3. 查看文件的 MD5 值
// JavaScript 示例
const md5 = require('md5');
md5('Hello World');
// 'b10a8db164e0754105b7a99be72e3fe5'

计算文件的 MD5 值,用于:

  • 验证文件下载完整性
  • 检查文件是否被篡改
  • 文件去重识别

使用示例:

Terminal window
# Linux 命令行
md5sum filename.zip
# 结果
a1b2c3d4e5f6... filename.zip

为防止彩虹表攻击,在原始数据前添加随机字符串(盐值):

const salt = 'random_salt_123';
const password = 'user_password';
const saltedHash = md5(salt + password);
// 结果与直接 md5(password) 完全不同

加盐的好处:

  • 相同密码产生不同哈希值
  • 防止彩虹表攻击
  • 提高安全性

最佳实践:

  • 每个用户使用不同的盐值
  • 盐值长度至少 16 位
  • 盐值随机生成并安全存储

通过多次迭代计算增加破解难度:

let hash = password;
for (let i = 0; i < 1000; i++) {
hash = md5(hash + salt);
}

常用迭代次数:

  • 1000 次 - 基础安全
  • 10000 次 - 推荐
  • 100000 次 - 高安全

使用密钥的 MD5 哈希,用于消息认证:

const crypto = require('crypto');
const hmac = crypto.createHmac('md5', 'secret_key');
hmac.update('message');
console.log(hmac.digest('hex'));

应用场景:

  • API 请求签名
  • 数据完整性验证
  • 消息认证

一次性计算多个文本或文件的 MD5:

  1. 输入多行文本(每行一个)
  2. 或选择多个文件
  3. 批量计算并导出结果

验证两个 MD5 值是否匹配:

原始 MD5: b10a8db164e0754105b7a99be72e3fe5
计算 MD5: b10a8db164e0754105b7a99be72e3fe5
结果: ✅ 匹配

不推荐(简单 MD5):

// 不安全!容易被彩虹表破解
const hashedPassword = md5(userPassword);

推荐(加盐 + 多次加密):

const crypto = require('crypto');
function hashPassword(password, salt) {
let hash = crypto.createHash('md5');
hash.update(salt + password);
// 多次迭代
for (let i = 0; i < 1000; i++) {
hash = crypto.createHash('md5');
hash.update(hash.digest('hex') + salt);
}
return hash.digest('hex');
}
// 使用
const salt = crypto.randomBytes(16).toString('hex');
const hashed = hashPassword('userPassword', salt);
// 存储: { salt, hashed }

下载文件后验证 MD5:

Terminal window
# 下载文件
wget https://example.com/file.zip
# 计算 MD5
md5sum file.zip
# 输出: a1b2c3d4... file.zip
# 与官方提供的 MD5 对比
# 如果一致,说明文件完整

防止 API 请求被篡改:

// 客户端
const params = {
timestamp: Date.now(),
userId: '12345',
action: 'getData'
};
// 按参数名排序并拼接
const sortedParams = Object.keys(params).sort().map(k => `${k}=${params[k]}`).join('&');
// 添加密钥并计算 MD5
const sign = md5(sortedParams + '&key=secret_key');
// 发送请求
params.sign = sign;
fetch('/api/data', {
method: 'POST',
body: JSON.stringify(params)
});
// 服务端验证
function verifySign(params, secretKey) {
const receivedSign = params.sign;
delete params.sign;
const sortedParams = Object.keys(params).sort().map(k => `${k}=${params[k]}`).join('&');
const calculatedSign = md5(sortedParams + '&key=' + secretKey);
return receivedSign === calculatedSign;
}

使用 MD5 生成缓存键:

function getCacheKey(params) {
const sortedParams = Object.keys(params).sort().reduce((acc, key) => {
acc[key] = params[key];
return acc;
}, {});
return 'cache:' + md5(JSON.stringify(sortedParams));
}
// 使用
const key = getCacheKey({ userId: 123, type: 'profile' });
// 相同的参数总是生成相同的 key

快速判断数据是否已存在:

const seenHashes = new Set();
function isDuplicate(data) {
const hash = md5(JSON.stringify(data));
if (seenHashes.has(hash)) {
return true;
}
seenHashes.add(hash);
return false;
}
用途不安全推荐
密码存储MD5bcrypt, Argon2
文件校验MD5SHA-256, SHA-3
数据完整性MD5SHA-256, BLAKE2
数字签名MD5SHA-256 + RSA

A: 理论上不可以,但可以通过以下方式破解:

  • 彩虹表 - 预计算的 MD5 对照表
  • 暴力破解 - 尝试所有可能的组合
  • 碰撞攻击 - 找到产生相同 MD5 的不同数据

Q: 两个不同的文件可能有相同的 MD5 吗?

Section titled “Q: 两个不同的文件可能有相同的 MD5 吗?”

A: 可能!这叫做「碰撞」。虽然概率极低,但已被证明可以实现。

Q: 为什么我的 MD5 和别人的不一样?

Section titled “Q: 为什么我的 MD5 和别人的不一样?”

A: 检查:

  • 编码方式(UTF-8 / GBK)
  • 是否包含换行符
  • 是否有首尾空格
  • 大小写是否一致

A: 不是! MD5 是哈希算法(散列函数),不是加密算法:

  • 加密 - 可逆,可以解密还原
  • 哈希 - 不可逆,无法还原

A: 使用流式计算,避免内存溢出:

const crypto = require('crypto');
const fs = require('fs');
const hash = crypto.createHash('md5');
const stream = fs.createReadStream('large-file.zip');
stream.on('data', chunk => hash.update(chunk));
stream.on('end', () => {
console.log(hash.digest('hex'));
});