前言
某些加密算法要求明文需要按一定长度对齐(例如DES/AES等),叫做块大小(BlockSize),比如16字节,那么对于一段任意的数据,加密前需要对最后一个块填充到16 字节,解密后需要删除掉填充的数据,这样加密前后数据就保持一致了。
定义
那么PKCS7Padding 和 PKCS5Padding的定义是什么呢,如下:
-
PKCS7Padding:假设数据长度需要填充n(n>0)个字节才对齐,那么填充n个字节,每个字节都是n;如果数据本身就已经对齐了,则填充一块长度为块大小的数据,每个字节都是块大小。
-
PKCS5Padding: PKCS7Padding 的子集,块大小固定为8字节。
实现
def pkcs5padding(data):
return pkcs7padding(data, 8)
def pkcs7padding(self, data, block_size=16):
if type(data) != bytearray and type(data) != bytes:
raise TypeError("仅支持 bytearray/bytes 类型!")
pl = block_size - (len(data) % block_size)
return data + bytearray([pl for i in range(pl)])
实例 (AES/ECB/128Bit)
class AesEcbCrypt():
def __init__(self, key):
self.key = key
def pkcs5padding(self, data):
return self.pkcs7padding(data, 8)
def pkcs7padding(self, data, block_size=16):
if type(data) != bytearray and type(data) != bytes:
raise TypeError("仅支持 bytearray/bytes 类型!")
pl = block_size - (len(data) % block_size)
return data + bytearray([pl for i in range(pl)])
def encrypt(self, data):
data = self.pkcs7padding(data, 16)
return AES.new(self.key, AES.MODE_ECB).encrypt(data)
def decrypt(self, data):
aes = AES.new(self.key, AES.MODE_ECB)
decrypt_text = aes.decrypt(data)
return decrypt_text[:-int(decrypt_text[-1])]
if __name__ == '__main__':
key = bytearray.fromhex("162CCDE5543E821AB101E159493F5A79")
aes = AesEcbCrypt(key)
text = "#START好好学习,天天向上!END#"
en_byte = aes.encrypt(text.encode())
print("密文(HEX):", en_byte.hex().upper())
de_byte = aes.decrypt(en_byte)
print("明文:", de_byte.decode())
网友评论