前言
CBC全称为密码分组链接模式。不同于ECB模式,在CBC模式中,每个明文块先与前一个密文块儿进行异或后,在进行加密。这种加密模式很好的隐藏了明文的统计特性,但是同样也暴露出了一个很严重的缺点。本文将针对CBC模式的特点,详细讲解字节反转攻击的原理及应用。一、CBC加密模式
-
Plaintext:明文
-
IV:初始化向量
-
Ciphertext:加密后的数据
-
Key:密钥
加密过程转化成文字来叙述:
- 先将Plaintext分组(常见以16字节为一组)
- 生成初始化向量IV和密钥Key(IV不需要保密,但一定要不可预测)
- 将IV和明文1组异或
- 将3中所得结果用Key进行加密,得到密文1组
- 将密文1组当作新IV与明文2组进行异或处理
- 将5中的结果用Key进行加密,得到密文2组
- 重复上述步骤,最后将IV和所有的密文分组拼接起来,得到最终密文
二、CBC解密模式
解密过程转化成文字来叙述:
- 从密文中提取出IV,并将密文分组
- 用Key将密文1组解密
- 2中解密的结果与IV异或,获得明文1组
- 密文1组成为新一轮的IV
- 重复上述步骤,将所有明文分组拼接后,得到最终明文
三、CBC字节反转攻击原理
字节反转攻击原理文字描述:
我们从上述图片可以看出,如果猜测出明文分组Pn,那么可以通过修改密文分组Ci-1为Ci-1 XOR Pn XOR A,那么解密出来的Pn的结果是A。当然我们一般是不可能直接猜出来整个明文分组Pn,我们更多遇到的是上述图片描述的那样,仅知道Pn中部分明文。同样地,我们依旧可以发动字节反转攻击,仅需要针对正确的位置进行修改密文内容即可。
这种攻击的精髓在于:通过CBC的加密特点改变明文内容,但是这种改变并不会引起其它明文块儿对应位的改变。这种攻击常用来绕过过滤器,提权(比如从guest变为admin)等。
四、CBC字节反转攻击例题
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
import base64
with open('./flag.txt','r') as f:
FLAG = f.readline().strip()
#print(FLAG)
BLOCK_SIZE=16
IV = get_random_bytes(BLOCK_SIZE)
key = get_random_bytes(BLOCK_SIZE)
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * chr(BLOCK_SIZE - len(s) % BLOCK_SIZE).encode()
unpad = lambda s: s[:-ord(s[len(s) - 1:])]
prefix = "flag="+FLAG+"&userdata="
suffix = "&user=guest"
def menu():
print ("1. encrypt")
print ("2. decrypt")
return input("> ")
def encryp