简介
“块加密”,如其名所言,每次加密需要以块为单位进行。显然实际应用中,明文不会理想若长度总为块大小(Block
size)的整倍数,故要以某种方式对其进行填充。
单论“填充”之法似乎并无太多讲究,但任何Padding都应满足以下要求:
- Padding只是追加部分,所以应当在满足块大小要求的前提下尽可能短;
- Padding应当易于被辨别和移除,故显然不能在明文后添加随机/固定的明文常用字节填充之;
- Padding应具备一定的冗余校验功能,解填充(Unpad)时最好可以校验填充是否正确。
由此,主流的Padding方案存在的一个共性也就不难解释了:Padding追加字节数应不小于1,且不大于块大小。
常用填充方案
常用的Padding方案有:pkcs7 , iso7816 , x923 。
pkcs7 :最为常用的一种padding方案。
设信息长度为 \(l_m\),块长度为 \(S\),其填充长度 \(l_p = S - (l_m \bmod S)\),填充字节亦是 \(l_p\)。
如块大小为16时,crypto{flag}
将被填充为crypto{flag}\x04\x04\x04\x04
。
相应地,解填充时取最后一个字节并记为 \(b\),判断 \(b \leq S\) 且最后 \(b\) 个字节均为 \(b\) 时,解填充校验成功,移除最后 \(b\) 个字节即视为解填充完成。
1
2
3
4
5
6
7
8
9
10
11
12def pkcs7_pad(msg:bytes,blocksize:int = 16):
p = blocksize - len(msg) % blocksize
return msg + bytes([p] * p)
def pkcs7_unpad(msg:bytes,blocksize:int = 16):
up = msg[-1]
for i in msg[-up:]:
if i != up:
raise UnpadError("Invalid Padding")
return msg[:-up]iso7816:填充规则较 pkcs7 更简单,填充长度同样是 \(l_p = S - (l_m \bmod S)\)。
区别是,其在原字节后填充一个'1'后全部填'0'(以bit位看),宏观上形如\x80\x00\x00...\x00
。md5即近似采用这种方式对待散列数据进行填充(区别是其填充的标定长度是 \(l \equiv 448 (\bmod 512)\))。
下述实现假定块大小为16:
1
2
3
4
5
6
7
8
9
10
11
12
13def iso7816_pad(msg:bytes):
p = 16 - len(msg) % 16
return msg + bytes([128] + [0] * (p - 1))
def iso7816_unpad(msg:bytes):
i = 1
while True:
if msg[-i] == 0:
i += 1
elif msg[-i] == 128:
return msg[:-i]
else:
raise UnpadError("Invalid Padding")x923:填充长度同上,最后一个字节为填充长度,其余填充字节为0。
1
2
3
4
5
6
7
8
9
10
11
12def x923_pad(msg:bytes):
p = 16 - len(msg) % 16
return msg + bytes([0] * (p-1) + [p])
def x923_unpad(msg:bytes):
up = msg[-1]
for i in range(2,up):
if msg[-i] != 0:
raise UnpadError("Invalid Padding")
return msg[:-up]
pycryptodome
再度发挥神威:Crypto.Util.Padding
提供了pad
和unpad
函数来协助执行常用的填充/解填充方案。
Padding Orcale
靶子简介
Padding Orcale Attack是一种针对C/S系统的攻击,利用了服务端解密后对密文进行unpad校验结果对应的相应差分。其本质上是一种适应性选择密文攻击。
假设存在一个Orcale,其会对传入的密文(AES-CBC模式加密)进行解密,根据解密结果做出不同相应:
- 若解密成功(填充校验正确)且明文内容正确,返回 A
- 若解密失败(填充校验错误),返回 B
- 若解密成功(填充校验正确),但明文内容不正确,返回 C
根本上来说,一个未被恰当设计的服务端很容易暴露其解密阶段、业务校验阶段失败间的相应差分,并被Padding Orcale的攻击者利用。参考如下的代码:
1 | from Crypto.Cipher import AES |
攻击
Padding Orcale 针对的主要是CBC模式分组加密的密文。针对别的模式或有更适合的攻击方法
比如ECB压根不需要Padding Orcale
回顾AES-CBC模式加密的特性: