关于CBC模式下的加密和解密,这里不过多阐述,可以参见 分组密码工作模式。
对于CBC解密可以用以下式子表示:
- Plaintext-1 = Decrypt(Ciphertext-1) XOR IV 只用于第一个组块
- Plaintext-N = Decrypt(Ciphertext-N) XOR Ciphertext-N-1 用于第二及剩下的组块
比特翻转攻击
从CBC解密表达式可以知道,得到明文的前一步操作是异或操作,改变密文中的一位
只会导致其对应的明文块完全改变,下一个明文块中的对应位
发生改变,而不会影响到其它明文块的内容。
因此,修改IV可以操纵解密出的第一组明文,修改某一个密文分组可以操纵后一个解密出的明文分组,也就是说CBC模式存在两个攻击点:
- IV向量,影响第一个明文分组
- 第N个密文分组, 影响第N+1个明文分组
因此对IV和密文分组进行比特翻转攻击,可以伪造某个明文分组对应的比特位。
这里给出如下Demo程序,输入参数a
为AES CBC模式加密后的密文(16进制形式),程序输出解密后的部分明文信息(id, name, email),要求伪造密文,使得明文id
对应的值为0
, 程序如下:
1 |
|

已知密文长度为48 bytes, 若要改变明文id的值,假设id在第N块明文中第x个字符,表示为N[x]
(x从1开始),这里仅简单假设id为单字符,则改变密文N-1[x]
或IV[x], 即可伪造我们需要的id值。显然,我们需要一种方案快速定位到相应的密文位置或IV位置。
已知XOR异或运算: X xor Y = Z, X、Y、Z三个数任意两个运算都可得到第三个。
若不考虑IV, 则明文id肯定可以表示为 id=A XOR B
,A是我们可控用来伪造id的密文值,那么改变密文A为:A1 = id
, 则得到的明文id为A1 XOR B = A XOR B XOR B = A
, 即判断明文id是否修改为A
,就能知道是否找到相应的密文位置N-1[x]
。假设我们需要伪造的id为fake_id
, fake_A= A XOR id XOR fake_id
, 得到的明文id就是fake_A XOR B = A XOR id XOR fake_id XOR B = fake_id
, 伪造id成功。 程序实现如下:
1 | #!/usr/bin/env python |
得到结果:
1 | make a=89b52bac0331cb0b393c1ac828b4ee0e07861f030a8a3dc4b6e786f473b52182000a0d4ce2145994573a92d257a514d1, get id='0' |
应用条件
能获取明文信息,密文或IV可控