📝 博客 · 2026-08-02 · ⏱ 15 分钟

文件哈希校验:MD5/SHA256

文件哈希校验教程:MD5/SHA1/SHA256 算法对比、文件完整性验证、密码存储、数字签名应用。

文件哈希MD5SHA256完整性校验

文件哈希校验:MD5/SHA256

下载文件被篡改、传输过程出错、确保文件完整性——哈希校验是基础工具。本文详解 MD5/SHA256 等。

什么是哈希?

哈希(Hash)是把任意长度数据映射为固定长度字符串的函数:

输入:Hello, World!
MD5:6cd3556deb0da54bca060b4c39479839
SHA256:dffd6021bb2bd5b0af676290809ec3a53191a81...

特性

  1. 定长输出:无论输入多长,输出固定长度
  2. 单向:从哈希反推原数据不可能
  3. 唯一性:相同输入永远相同输出
  4. 雪崩效应:输入微小变化,输出完全不同

用途

常见哈希算法

MD5

SHA-1

SHA-256

SHA-3

BLAKE2/3

52tool 哈希工具

工具地址:哈希计算

功能

实战 1:文件哈希

上传文件 report.pdf

MD5:a3f5b8c1d2e4f6a7b9c8d0e1f2a3b4c5
SHA-1:b89ea7c5d4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9
SHA-256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4...

实战 2:文本哈希

输入:

Hello, World!

输出:

MD5:6cd3556deb0da54bca060b4c39479839
SHA-256:dffd6021bb2bd5b0af676290809ec3a53191a8111c...

实战 3:HMAC

输入:

消息:Hello
密钥:secret
算法:HMAC-SHA256

输出:

HMAC:8c54e8e2a4c81e2b8b4b6d1f3a5e7c9d...

文件完整性校验

校验流程

  1. 文件提供方计算哈希(如 SHA-256)
  2. 公布哈希值
  3. 下载方下载文件
  4. 重新计算哈希
  5. 对比哈希,一致则文件完整

实战:校验下载文件

Linux ISO 下载:

提供方:
ubuntu-24.04.iso
SHA256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4...

下载方:
$ sha256sum ubuntu-24.04.iso
e3b0c44298fc1c149afbf4c8996fb92427ae41e4...  ubuntu-24.04.iso

哈希一致,文件未篡改。

工具

Windows:

Get-FileHash file.zip -Algorithm SHA256

或用 52tool 哈希工具上传文件计算。

Linux/Mac:

md5sum file.zip
sha1sum file.zip
sha256sum file.zip

编程实现

JavaScript

// 文本哈希
async function hashText(text, algorithm = 'SHA-256') {
  const buffer = new TextEncoder().encode(text);
  const hash = await crypto.subtle.digest(algorithm, buffer);
  return Array.from(new Uint8Array(hash))
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');
}

await hashText('Hello');  // SHA-256 哈希

// 文件哈希
async function hashFile(file, algorithm = 'SHA-256') {
  const buffer = await file.arrayBuffer();
  const hash = await crypto.subtle.digest(algorithm, buffer);
  return Array.from(new Uint8Array(hash))
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');
}

Python

import hashlib

# 文本
hash_md5 = hashlib.md5(b'Hello').hexdigest()
hash_sha256 = hashlib.sha256(b'Hello').hexdigest()

# 文件
def hash_file(path, algorithm='sha256'):
    h = hashlib.new(algorithm)
    with open(path, 'rb') as f:
        while chunk := f.read(8192):
            h.update(chunk)
    return h.hexdigest()

# HMAC
import hmac
h = hmac.new(b'secret', b'Hello', hashlib.sha256).hexdigest()

命令行

# 文本
echo -n "Hello" | md5sum
echo -n "Hello" | sha256sum

# 文件
md5sum file.zip
sha256sum file.zip

Java

import java.security.MessageDigest;

MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest("Hello".getBytes());

StringBuilder sb = new StringBuilder();
for (byte b : hash) {
    sb.append(String.format("%02x", b));
}
String hexHash = sb.toString();

实战场景

场景 1:校验下载文件

1. 从官网下载 ISO 文件
2. 官网提供 SHA256 校验值
3. 本地 sha256sum 计算
4. 对比,一致则文件未被篡改

场景 2:密码存储

import hashlib, os

def hash_password(password):
    salt = os.urandom(32)
    hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000)
    return salt + hash

def verify_password(password, stored):
    salt = stored[:32]
    hash = stored[32:]
    new_hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000)
    return new_hash == hash

不要直接 SHA256 密码,要用 PBKDF2/bcrypt/Argon2 等慢哈希。

场景 3:文件去重

# 计算每个文件哈希
hashes = {}
for file in files:
    h = hash_file(file)
    if h in hashes:
        print(f'{file} 与 {hashes[h]} 相同')
    else:
        hashes[h] = file

场景 4:API 签名

import hmac, hashlib

def sign_request(params, secret):
    message = '&'.join(f'{k}={v}' for k, v in sorted(params.items()))
    signature = hmac.new(secret.encode(), message.encode(), hashlib.sha256).hexdigest()
    return signature

场景 5:Git 提交哈希

Git 用 SHA-1 标识提交。每次 commit 生成唯一哈希:

commit a3f5b8c1d2e4f6a7b9c8d0e1f2a3b4c5d6e7f8a9

参考 52tool 哈希工具 验证 Git commit 完整性。

场景 6:区块链

区块链用 SHA-256 链接区块:

区块 N 哈希 = SHA256(区块 N 内容 + 区块 N-1 哈希)

篡改任何区块都会导致后续哈希变化。

哈希碰撞

什么是碰撞?

两个不同输入产生相同哈希:

输入 1 → 哈希 X
输入 2 → 哈希 X

MD5 碰撞

2004 年王小云团队发现 MD5 碰撞,能在数小时内生成两个不同文件有相同 MD5。

SHA-1 碰撞

2017 年 Google 公开 SHA-1 碰撞,SHAttered 攻击。

SHA-256 安全

截至 2026 年无已知实际攻击,仍是安全选择。

碰撞的影响

慢哈希 vs 快哈希

快哈希

MD5、SHA-256:每秒计算百万次。适合文件校验,不适合密码存储(暴力破解快)。

慢哈希

bcrypt、PBKDF2、Argon2:故意慢(每次 100ms+),暴力破解成本极高。用于密码存储。

加盐

为什么加盐?

不加盐:相同密码哈希相同,彩虹表攻击可行。

密码 "123456" → 哈希 X
所有用户用 "123456" 都得到哈希 X
攻击者查彩虹表得到原密码

加盐

用户 A:密码 "123456" + 盐 "abc" → 哈希 Y
用户 B:密码 "123456" + 盐 "xyz" → 哈希 Z

不同用户相同密码哈希不同。

实践

import hashlib, os

salt = os.urandom(32)  # 每个用户不同
hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt, 100000)

常见问题

Q: MD5 还能用吗?

A: 非安全场景能用(如文件去重、缓存键)。安全场景(密码、签名)不能用。

Q: SHA-1 还能用吗?

A: 不建议。已被弃用,用 SHA-256。

Q: 怎么存密码?

A: 用 bcrypt、PBKDF2、Argon2 等慢哈希 + 加盐。不要直接 SHA256。

Q: 哈希能反推原数据吗?

A: 不能。哈希是单向函数。

Q: 怎么验证文件完整性?

A: 计算文件 SHA-256,与官方提供的哈希对比。一致则未篡改。

Q: 工具会泄露我的文件吗?

A: 52tool 哈希工具在浏览器端运行,文件不上传服务器。适合处理敏感文件。

常见问题解答

Q: 怎么计算文件 SHA256?

A: Windows: Get-FileHash file.zip -Algorithm SHA256。Linux: sha256sum file.zip。或用 52tool 哈希工具 上传文件计算。

Q: MD5 和 SHA256 哪个好?

A: SHA256。MD5 已被破解,不安全。文件校验也建议用 SHA256。

Q: 怎么验证下载文件?

A: 1) 下载文件;2) 计算本地 SHA256;3) 与官方哈希对比;4) 一致则文件完整。

Q: 密码能直接 SHA256 存吗?

A: 不能。直接 SHA256 易被彩虹表攻击。用 PBKDF2/bcrypt/Argon2 加盐慢哈希。

Q: 哈希碰撞是什么?

A: 两个不同输入产生相同哈希。MD5 和 SHA1 已被破解(可人为制造碰撞),SHA256 安全。

Q: HMAC 和普通哈希区别?

A: HMAC 是带密钥的哈希(Hash-based MAC),用于消息认证。普通哈希无密钥,任何人可计算。

总结

哈希是数据完整性的基石:

记住:MD5 不用于安全密码用慢哈希加盐SHA-256 是安全默认