高级 #crypto#cryptanalysis#attack

密码分析

密码分析(Cryptanalysis)是研究如何破解密码系统的科学——从频率分析破解古典密码到侧信道攻击窃取现代密钥,攻防对抗推动密码学发展

🕵️ 攻防对抗——密码学进步的动力

密码学的每一次进步,都来自一次成功的”破解”。

古典密码 → 被频率分析破解 → 催生了维吉尼亚密码
维吉尼亚 → 被 Kasiski 破解 → 催生了更复杂的机械密码
Enigma   → 被图灵破解   → 催生了现代密码学
DES      → 被暴力破解   → 催生了 AES
MD5/SHA-1→ 被碰撞攻击破解→ 催生了 SHA-256/3
RSA      → 量子 Shor 算法威胁 → 催生了后量子密码

密码分析(Cryptanalysis) 就是”攻击密码系统的科学”——不是搞破坏,而是发现密码系统中的弱点,推动密码学向前发展。

📐 一个核心原则:密码系统应该是公开的——安全性只依赖密钥的保密性,不依赖算法的保密性(Kerckhoffs 原则)。


📊 攻击者的能力——四种模型

攻击类型攻击者知道什么类比
唯密文攻击只截获了一些密文偷看一封信,但看不懂
已知明文攻击密文 + 对应的部分明文知道”今天天气”加密成了”XXXYYY”
选择明文攻击可以让加密任意选择的明文拿任意文件让系统签名
选择密文攻击可以让解密任意选择的密文拿任意密文让系统解密看结果
攻击难度:唯密文 > 已知明文 > 选择明文 > 选择密文
攻击者掌握的信息越多(选择能力越强)→ 攻击越容易
一个好的密码算法,需要能抵抗"选择明文攻击"。

🔧 经典攻击方法

① 暴力破解(Brute Force)

尝试所有可能的密钥——最简单也最”笨”的方法。

# 暴力破解对密钥长度的敏感性
# 假设每秒尝试 10⁹ 个密钥

keys = {
    "DES (56位)":       2**56,     # 约 2 年
    "AES-128 (128位)":  2**128,    # 约 10²⁰ 年
    "AES-256 (256位)":  2**256,    # 宇宙年龄都远远不够
}

# 所以:128 位的密钥,暴力破解就已经不可行了

② 频率分析(Frequency Analysis)

利用语言的统计特性——英文中最常见的字母是 E,其次是 T、A、O……

# 对单表替换密码的频率分析
cipher = "KHOOR ZRUOG"  # "HELLO WORLD" 用密钥 3 加密

# 统计密文中每个字母的出现次数
from collections import Counter
freq = Counter(cipher.replace(" ", ""))

# 密文中出现最多的字母 → 大概率是 E 加密后的结果
# KHOOR 中 O 出现 3 次 → O 很可能是 E → O-E 位移 10
# 验证:H(7)+10=R(17) → 确实!密钥是 10

③ 中间相遇攻击(Meet-in-the-Middle)

针对”双重加密”的攻击:

# 如果 E1 和 E2 是两个不同的加密算法
# 双重加密:C = E2(E1(M, K1), K2)
# 中间相遇攻击:
#   从左边:尝试所有 K1,记录 E1(M, K1)
#   从右边:尝试所有 K2,记录 D2(C, K2)
#   找匹配 → 同时破解了 K1 和 K2
#  复杂度从 2^(n+m) 降至 2^(max(n,m)+1)

这就是为什么 3DES(三次 DES)的实际安全性只有 112 位,而不是 168 位。


⚡ 侧信道攻击——不破解算法,破解实现

侧信道攻击(Side-Channel Attack) 不攻击密码算法本身——而是利用密码实现的物理泄露。

# ❌ 不安全的实现——比较时间是变量
def compare_password(input, stored):
    for i in range(len(stored)):
        if input[i] != stored[i]:
            return False  # 在第一个不同的字符就返回了
        time.sleep(0.01)  # 每个字符比对耗时不同!
    return True

# 攻击者:测量每次返回的时间差异
# 第一个字符对了 → 耗时 > 0.01s
# 第一个字符错了 → 耗时 < 0.01s
# → 逐位猜出密码!这就是"时序攻击(Timing Attack)"
# ✅ 安全的实现——固定时间比较
def constant_time_compare(a, b):
    if len(a) != len(b):
        return False
    result = 0
    for i in range(len(a)):
        result |= ord(a[i]) ^ ord(b[i])  # 始终比较所有位
    return result == 0

常见的侧信道攻击

攻击利用什么经典案例
时序攻击加密时间与密钥/数据的相关性远程猜出 RSA 私钥
功耗分析CPU 执行不同指令的功耗不同从智能卡芯片读出 AES 密钥
电磁攻击芯片工作时辐射电磁信号从手机中提取密钥
缓存攻击缓存命中率的差异Meltdown/Spectre 漏洞
声学攻击风扇、电容的声波泄露从打印机声音还原打印内容

🛡️ 如何防御?

攻击防御
暴力破解足够长的密钥(≥128 位)
频率分析用现代分组密码(不是单表替换)
时序攻击常数时间算法
缓存攻击清除敏感数据后的缓存、不使用共享内存
量子攻击后量子密码(Kyber、Dilithium)

📝 小结

概念一句话
密码分析研究如何破解密码系统的科学
攻击模型唯密文 < 已知明文 < 选择明文 < 选择密文
暴力破解尝试所有密钥——密钥 ≥ 128 位后不可行
频率分析利用语言统计特性——破解替换密码
侧信道攻击利用物理泄露——不破解算法,破解实现
Kerckhoffs 原则密码系统安全性只依赖密钥保密性

🎯 思考题:Kerckhoffs 原则说”算法应该是公开的,安全性只依赖密钥”——这和”安全通过隐蔽”(Security by Obscurity,把算法藏起来)有什么根本不同?为什么前者是好的设计原则,后者不是?

为什么先学这个? 密码分析是密码学板块的最后一节。至此密码学 9 个节点全部完成。你可以进入其他板块继续探索。