使用AES-256-CBC进行加密解密,填充规则为PKCS7,实现方法为Python:
import base64
import pyaes
# 把明文按照block_size进行拆分
def split_to_data_blocks(byte_str, block_size=16):
length = len(byte_str)
j, y = divmod(length, block_size)
blocks = []
remnant = j * block_size
for i in range(j):
start = i * block_size
end = (i + 1) * block_size
blocks.append(byte_str[start:end])
stext = byte_str[remnant:]
if stext:
blocks.append(stext)
return blocks
# Plaintext: I don't like deadbeef. 你呢?
# Ket: 1UO7ZnmwcT7KtScS2hAZV+aZ1Gk95HPK1EqcXT6rqoU=
# IV: 6GXIzJ0GD/76WkTtgmaDYQ==
# 初始化明文、密钥、偏移量
# plaintextStr = "I don't like deadbeef. 你呢?"
# keyStr = "1UO7ZnmwcT7KtScS2hAZV+aZ1Gk95HPK1EqcXT6rqoU="
# IVStr = "6GXIzJ0GD/76WkTtgmaDYQ=="
plaintextStr = input("Plaintext: ")
keyStr = input("KeyStr: ")
IVStr = input("IVStr: ")
# 把明文编码成Bytes,把密钥和偏移量解码成Bytes
plaintextBytes = plaintextStr.encode('utf-8')
keyBytes = base64.b64decode(keyStr)
IVBytes = base64.b64decode(IVStr)
plaintextBytesLength = len(plaintextBytes) # 记录明文Bytes长度,方便解密
# 使用PKCS7填充明文
block_size = 16
s = plaintextBytes
bs = block_size
plaintextPadding = s + (bs - len(s) % bs) * chr(bs - len(s) % bs).encode()
print(plaintextPadding.hex()) # 把填充后的明文(Bytes)按十六进制输出
# 使用CBC加密规则
cbc = pyaes.AESModeOfOperationCBC(keyBytes, IVBytes)
blocks = split_to_data_blocks(plaintextPadding)
ciphertextBytes = b''
for x in blocks:
ciphertextBytes = ciphertextBytes + cbc.encrypt(x)
ciphertextBase64 = base64.b64encode(ciphertextBytes)
ciphertextStr = ciphertextBase64.decode('utf-8')
print(ciphertextStr)
# 解密,首先判断密文长度是否满足要求
unpadded_ciphertextBytes = b'' # 得到未填充的密文
if len(ciphertextBytes) != plaintextBytesLength:
print("not identical")
k = plaintextBytesLength / block_size # 保留前k个block
for i in range(int(k)):
start = i * block_size
end = (i + 1) * block_size
unpadded_ciphertextBytes = unpadded_ciphertextBytes + ciphertextBytes[start:end]
# 使用CBC对密文解密
cbc = pyaes.AESModeOfOperationCBC(keyBytes, IVBytes)
decoded_text_bytes = b''
for x in split_to_data_blocks(unpadded_ciphertextBytes):
decoded_text_bytes = decoded_text_bytes + cbc.decrypt(x)
print(decoded_text_bytes.hex()) # 输出解密后未填充的明文
print(decoded_text_bytes.decode('utf-8')) # 输出解密后的字符串str