一:哈希算法介绍
1.哈希算法定义
哈希算法是一种单向函数,能将的输入数据(如文本、文件、二进制流)转换为的唯一字符串(称为哈希值、散列值或摘要)。例如:
哈希算法是将任意长度数据转换为固定长度摘要的单向函数,具备确定性、不可逆性及雪崩效应。本文详解 MD5 等算法原理,展示 Python 实现方式,涵盖数字签名、文件防篡改等应用场景,并分析 MD5 碰撞攻击与彩虹表破解风险,建议在高安全场景使用 SHA-256 等现代算法。

哈希算法是一种单向函数,能将的输入数据(如文本、文件、二进制流)转换为的唯一字符串(称为哈希值、散列值或摘要)。例如:
e4d909c290d0fb1ca068ffaddf22cbd0)。核心特性
别名与关联概念
| 特性 | 说明 | 示例或数学表达 |
|---|---|---|
| 确定性 | 相同输入必定生成相同的哈希值。 | H("hello") ≡ 2cf24dba...(SHA-256) |
| 敏感性(雪崩效应) | 输入数据的微小变化(如1比特)会导致哈希值完全不同。 | 修改 hello → hallo → 7838a484...(SHA-256) |
| 快速性 | 无论输入数据大小,均能快速计算出哈希值。 | 计算速度:SHA-256 ≈ 200MB/s(现代 CPU) |
| 单向性 | 无法从哈希值逆向推导出原始输入数据。 | 已知 H(x),无法解出 x(除非暴力破解) |
| 强抗碰撞性 | 极难找到两个不同输入产生相同的哈希值,碰撞概率极低(哈希空间为 2^n,n为哈希长度)。 | 碰撞概率 ≈ 1/(2^n)(如MD5的 n=128) |
2^n(n为位数),如:
n=128 → 结果空间 2^128(约3.4×10^38种可能)n=256 → 结果空间 2^256(约1.1×10^77种可能)√(2^n)。| 分类 | 全称 | 代表算法 | 输出长度 | 安全性 | 典型应用场景 |
|---|---|---|---|---|---|
| CRC | 循环冗余校验(Cyclic Redundancy Check) | CRC-32 | 32位 | 非加密 | 网络传输错误检测、存储校验 |
| MD | 消息摘要算法(Message Digest) | MD5 | 128位 | 不安全 | 旧版文件校验(已淘汰) |
| SHA | 安全哈希算法(Secure Hash Algorithm) | SHA-1 | 160位 | 不安全 | 旧版数字签名(已淘汰) |
| SHA | 安全哈希算法(Secure Hash Algorithm) | SHA-256 | 256位 | 安全 | 比特币、SSL证书、密码存储 |
| SHA | 安全哈希算法(Secure Hash Algorithm) | SHA-512 | 512位 | 安全 | 高安全性需求场景(如军事) |
每 32 位一组共四组 128 位 (A,B,C,D。四个寄存器
A = 0x67452301
B = 0xEFCDAB89
C = 0x98BADCFE
D = 0x10325476
**N(长度)≡448(mod512) 如果不满足进行填充。前 448 位:放原始数据 + 填充的 1(标记填充开始位置)和 0,后 64 位:记录原始数据长度
总长度 = 原始长度 + 填充的 1 和 0 + 64 位长度记录**
举个栗子

假设原始数据是 1000 字节(8000 位),填充步骤如下:
步骤 1:填充 1 个 1 和若干个 0
1:变成 8001 位。0 直到长度 ≡ 448 mod 512:
1)。步骤 2:附加 64 位的原始长度
(1) 填充后的数据总长度
(2) 切割成 512 位块
(3) 每个块细分为 16 个 32 位子块
四轮循环(每轮使用不同的非线性函数和位移数)
每轮需要 16 次操作四轮共需要 64 次操作
**与(AND):用符号'∧'表示,表示同时满足两个命题的关系。
或(OR):用符号'∨'表示,表示两个命题中至少一个为真的关系。
非(NOT):用符号'¬'表示,表示否定或取反的关系。
异或(⊕):**同为 0,异为 1
| 轮次 | 函数 | 逻辑表达式 | 行为特点 |
|---|---|---|---|
| 1 | F(B,C,D) | (B ∧ C) ∨ (¬B ∧ D) | 根据 B 选择 C 或 D |
| 2 | G(B,C,D) | (B ∧ D) ∨ (C ∧ ¬D) | 根据 D 选择 B 或 C |
| 3 | H(B,C,D) | B ⊕ C ⊕ D | 三者的异或(奇偶校验) |
| 4 | I(B,C,D) | C ⊕ (B ∨ ¬D) | 复杂混合,打破对称性 |
每当一个块完成四轮循环后得到的 A,B,C,D 和初始值 A,B,C,D 进行如下操作

**Ainitial,Binitial,Cinitial,Dinitial:处理当前块前的寄存器初始值
Acurrent,Bcurrent,Ccurrent,Dcurrent:四轮循环后的寄存器当前值。
Mod 2^32=当两个 32 位无符号整数相加的结果超过 32 位(即 ≥2^32)时,超出部分的高位被丢弃,仅保留低 32 位。也叫溢出自动取模**
然后将更新后的寄存器值 Anew,Bnew,Cnew,Dnew 作为下一个 512 位块的初始值,重复四轮循环操作
当所有 512 位块处理完毕后(也就是处理 N 次),最终的哈希值由最后一次更新的寄存器按小端字节序输出 128 位哈希值值拼接而成:
A = 0x5D41402A → 2A 40 41 5D
B = 0xBC4B2A76 → 76 2A 4B BC
C = 0xB9719D91 → 91 9D 71 B9
D = 0x1017C592 → 92 C5 17 10
拼接结果:5d41402abc4b2a76b9719d911017c592。
利用 python 直接将文件读取为哈希值

当前代码路径下放置文本文件进行读取

也可以利用如下工具

代码如下
from hashlib import md5
from hashlib import sha1
from hashlib import sha256
from hashlib import sha512
class StreamHash():
"""哈希摘要生成器"""
def __init__(self, algorithm='md5', size=1024):
self.size = size
alg = algorithm.lower()
if alg == 'md5':
self.hash = md5()
elif alg == 'sha1':
self.hash = sha1()
elif alg == 'sha256':
self.hash = sha256()
elif alg == 'sha512':
self.hash = sha512()
else:
raise ValueError('不支持指定的摘要算法')
# 魔法方法:让对象可以像函数一样被调用
def __call__(self, stream):
return self.to_digest(stream)
def to_digest(self, stream):
"""生成十六进制形式的哈希摘要字符串"""
for data in iter(lambda: stream.read(self.size), b''):
self.hash.update(data)
return self.hash.hexdigest()
def main():
# hash = md5()
sh = StreamHash()
with open('1.txt', 'rb') as stream:
# for buf in iter(lambda: stream.read(4096), b''):
# hash.update(buf)
# print(hash.hexdigest())
#print(sh(stream))
print(sh.to_digest(stream))
if __name__ == '__main__':
main()
# file_hash.py
crypto 库实现哈希值


python 生成的哈希值和网站 md5 值相同
# python 版本 3.x
# windows 安装依赖:pip install pycryptodome
# Linux 安装依赖: pip install pycrypto
from Crypto.Hash import MD5
obj1 = MD5.new()
obj1.update(b"123456")
print(obj1.hexdigest())
obj2 = MD5.new()
obj2.update("test_string".encode('utf-8'))
print(obj2.hexdigest())
# md5_crypto.py
hashlib 库实现哈希值

import hashlib
# 英文计算哈希值
m = hashlib.md5()
m.update(b'123456')
# 返回 16 进制字符串
print(m.hexdigest())
# 中文计算哈希值
data = 'test_string'
enc = data.encode(encoding='utf-8')
value = hashlib.md5(enc).hexdigest()
print(value)
# md5_hashlib.py

# python 版本 3.x
# windows 安装依赖:pip install pycryptodome
# Linux 安装依赖: pip install pycrypto
from Crypto.Hash import SHA1
sha1 = SHA1.new()
sha1.update("test_string".encode('utf-8'))
# print(sha1.digest())
# 返回字节串
print(sha1.hexdigest())
# 返回 16 进制字符串
与 sha1_crypto.py 代码结果相同

import hashlib
string='test_string'
sha1 = hashlib.sha1()
sha1.update(string.encode('utf-8'))
res = sha1.hexdigest()
print(res)
1→aX3f,2→gT7y),阻止顺序遍历。hash = bcrypt(password + salt)。hash 和 salt 到数据库。碰撞攻击
fastcoll、HashClash)自动生成碰撞文件。2^64 降至 2^40。1.攻击类型
| 攻击类型 | 原理/描述 | 工具/示例 | 防御措施 | 备注 |
|---|---|---|---|---|
| 暴力破解 | 穷举所有可能的明文组合,生成 MD5 哈希进行匹配。 | Hashcat、John the Ripper (如:hashcat -m 0 -a 3 <hash> ?a?a?a?a?a?a) | 1. 强制长密码(≥12 位) |
rockyou.txt)生成 MD5 哈希匹配。 | Hashcat、Hydra (如:hashcat -m 0 -a 0 <hash> rockyou.txt) | 1. 禁用弱密码库中的密码e10adc3949ba59abbe56e057f20f883e→123456) | 1. 强制加盐(随机盐值)2.优缺点
| 攻击类型 | 优点 | 缺点 |
|---|---|---|
| 暴力破解 | 1. 理论上可破解任何密码(覆盖全部可能性) |
3.总结对比
| 攻击类型 | 最佳适用场景 | 最弱防御场景 | 防御优先级 |
|---|---|---|---|
| 暴力破解 | 短密码、弱策略系统(如 6 位数字) | 无盐,短密码存储 | 强制长密码 + 慢哈希算法 |
| 字典攻击 | 用户使用常见弱密码 | 无密码复杂度策略的系统 | 禁用弱密码 + 多因素认证 |
| 查表法 | 未加盐的常见短密码 | 使用 MD5 且未加盐的遗留系统 | 加盐 + 升级哈希算法 |
| 彩虹表攻击 | 未加盐的历史密码库 | 早期未升级的数据库(如 MD5 明文存储) | 唯一盐值 + 密钥派生函数(如 PBKDF2) |
彩虹表的核心概念
彩虹表攻击图

彩虹表攻击时间
| 字符集 | 字母 | 字母 + 数字 | 字母 + 数字 + 常用符号 | 全部字符集 |
|---|---|---|---|---|
| 哈希链长度 | 2^100 | 2^400 | 12000 | 20000 |
| 哈希链个数 | 8000000 | 40000000 | 40000000 | 100000000 |
| 表单数量 | 5 | 7 | 13 | 20 |
| 成功率 | 99.9% | 99.9% | 99.9% | 99.3% |
| 文件大小 | 640MB | 4480MB | 8320MB | 32000MB |
| 最大生成时间 | 17 小时 | 5 天 14 小时 | 52 天 | 332 天 |
| 最大破解时间 | 7 秒 | 14 秒 | 11 分 | 48 分 |
彩虹表的优缺点
| 优点 | 缺点 |
|---|---|
| 1. 预计算后破解速度快(分钟级) | 1. 生成耗时(需数天至数周) |
| 2. 存储优化(链式结构) | 2. 无法破解加盐哈希 |
| 3. 覆盖常见短密码 | 3. 长密码或复杂字符集不适用 |
哈希算法通过不可逆计算将任意数据转换为固定长度的唯一摘要值,确保数据完整性、安全验证及身份认证,其安全性依赖抗碰撞能力,需选用如 SHA-256 等现代算法抵御攻击。
| 算法 | 输出长度(位) | 安全性 | 碰撞攻击 | 典型应用场景 | 现状与建议 |
|---|---|---|---|---|---|
| CRC-32 | 32 | 无安全性,仅用于错误检测 | 易构造碰撞(设计目标非抗碰撞) | 网络传输校验(如以太网帧)、文件完整性初检 | 不用于安全场景,仅保留在非安全校验场景。 |
| MD5 | 128 | 已破解(2004 年王小云团队实现高效碰撞攻击) | 可在数秒内生成碰撞(如 fastcoll 工具) | 历史遗留系统、非安全文件校验(如下载临时校验) | 完全弃用安全场景,升级为 SHA-256 或 SHA-3。 |
| SHA-1 | 160 | 已破解(2017 年 Google 的 SHAttered 攻击实现实际碰撞) | 理论成本约 2^63,实际攻击可行 | 旧版 SSL 证书、Git 版本控制(已逐步淘汰) | 立即替换,使用 SHA-256 或 SHA-3 替代。 |
| SHA-256 | 256 | 安全(目前无公开有效攻击) | 理论碰撞复杂度 2^128,实际不可行 | 比特币、数字签名、TLS/SSL 证书、密码存储(结合 KDF) | 推荐使用,适用于大多数安全场景。 |
| SHA-512 | 512 | 更安全(抗量子计算潜力优于 SHA-256) | 理论碰撞复杂度 2^256,安全性更高 | 高安全性需求场景(如军事加密、金融系统) | 推荐使用,适合对安全性和抗量子计算有更高要求的场景。 |

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online