CBC翻转字节攻击
CBC加解密回顾
加密
- 第一块明文在加密前需要先和IV异或,再进行加密得到密文1;
- 后续明文块需要先和前一块密文异或,再进行加密得到密文i
解密
- 第一块密文解密后需要先和IV异或,才能得到明文1
- 后续密文块解密后需要先和前一块密文异或,才能得到得到明文i
字节反转攻击
核心原理
由公式可以看到明文是由iv和密文共同决定的,因此可以通过控制iv或者上一块密文来控制密文输出
- 改iv可以控制第一块明文输出
- 改密文可以控制第i块明文输出
公式推导
1 | 已知IV ⊕ D(C1,K) = P1 |
所以如果想将明文从P1改为P1’,只需要将IV变为IV’,IV’的值可由已知条件按位异或得到:
1 | IV' = IV ⊕ P1 ⊕ P1' |
例题(flip-flop)
1 | #!/usr/bin/python3 |
题目分析
- 输入1执行加密,已知明文为NewStarCTFer____,会输出对应的iv+密文
- 输入2执行解密,需要用户输入iv+密文,控制明文输出为AdminAdmin______,得到flag
- 很明显已知iv、P和P1,只要修改IV为IV’即可,给出解密脚本
1
2
3
4
5
6
7
8
9
10
11def strxor(a1, a2):
return bytes([b1 ^ b2 for b1,b2 in zip(a1,a2)])
authcode = "f6ba55e71e855cc335be3731b4ec4b175c43472435505016500648a5f653fffc"
iv = bytes.fromhex(authcode)[:16]
c_origin = bytes.fromhex(authcode)[16:]
p_origin = b'NewStarCTFer____'
p_target = b'AdminAdmin______'
iv_modified = strxor(strxor(iv,p_origin),p_target)
authcode=iv_modified.hex()+c_origin.hex()
print(authcode)
局限性
- 密文长度小于单block长度时,仅控制iv即可控制整个明文输出
- 密文长度大于单block长度时,无法像单block长度那样完全自由控制整个明文,核心限制是 “控制后一块明文必须牺牲前一块明文”,仅靠CBC字节反转攻击无法实现整体控制。
防护建议
- 纯CBC只保证机密性,不保证完整性,可以放弃纯 CBC 模式,改用支持 机密性 + 完整性 + 真实性 的 AEAD(Authenticated Encryption with Associated Data)算法,AEAD 会自动对密文 + IV + 附加数据(AD)计算认证标签,篡改任何部分都会导致解密失败,直接杜绝字节翻转攻击。
- CBC 模式 + 独立完整性校验,MAC 计算范围必须覆盖 IV + 密文, 来保证IV和密文均不被篡改
本文作者:
yd0ng
本文链接: https://blog.yd0ng.top/2025/12/09/CBC%E7%BF%BB%E8%BD%AC%E5%AD%97%E8%8A%82%E6%94%BB%E5%87%BB/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!
本文链接: https://blog.yd0ng.top/2025/12/09/CBC%E7%BF%BB%E8%BD%AC%E5%AD%97%E8%8A%82%E6%94%BB%E5%87%BB/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!