aes数据填充问题-创新互联
问题
网页标题:aes数据填充问题-创新互联
分享链接:http://scyanting.com/article/dccshs.html
因为aes加解密对数据大小要求是16的倍数。但如果直接填充,等解密时不知道哪个字节是填充的,网上大多直接使用\x00填充尾部,然后把解密出来的数据直接使用s.rstrip()删除尾部的数据。
但如果原数据是以\x00结尾呢,则导致不能100%还原数据。
比如传输的程序不能运行了,大小不一样。。
设想,数据最后一位为标志位,用来储存填充位数。然后每当接受一组数据时,先获取标志位,然后就知道哪些位是填充的了,可以精准删除填充数据
假设原数据是’\x01\0x2’
这是2位数据,除去最后一位标志位,再填充13个\x00,最后一位使用\x0e填充(16进制,13为e)
最后填充的数据则是
'\x01\x02\x00\x00…\x0e’总共16位
下面是测试代码
a =b'\x01\x02\x03\x05'
len2 =15-len(a)%16
print("长度",len2)
for i in range(len2):
a+=b'\x00'
a += len2.to_bytes(1,'big') # 标志位,to_bytes是数字转为字节型
print("a填充",len(a),a)
#去除
len1 = len(a)
end = a[len1-1:len1] #获取标志位
sum = int.from_bytes(end,'big') #填充的个数
a = a[0:-(sum+1)]#切片,获取原数据
print(a)
下面是编写的加解密代码
#默认使用cbc加密方式,可以对文件二进制流进行加解密
from Crypto.Cipher import AES
import base64
#
class Aescrypt():
def __init__(self,key,model,iv):
self.key = key
self.model = model
self.iv = iv
def file_add16(self,par):#文件数据进行填充,在最后16位数据中,最后一位判断位,表示有几个是填充的
len1 = 15 - (len(par) % 16)#计算填充的个数
for i in range(len1):
par +=b'\x00'
par +=len1.to_bytes(1,'big')#标志位
return par
def aesencrypt_file(self,text):
text = self.file_add16(text)
self.aes = AES.new(self.key,self.model,self.iv)
self.encrypt_text = self.aes.encrypt(text)
return self.encrypt_text
def aesdecrypt_file(self,text):#aes cbc解密
self.aes = AES.new(self.key,self.model,self.iv)
try:
self.decrypt_text = self.aes.decrypt(text)
except:
print("数据不是16倍数",len(text),text)
#清除填充数据
data = self.decrypt_text
len1 = len(data)
end = data[len1-1:len1]#获取标志位
sum = int.from_bytes(end, 'big') # 填充的个数
self.decrypt_text = data[0:-(sum + 1)] # 切片,获取原数据
return self.decrypt_text
def decode(data,passwd = b"1234567812345678",iv = b'0000000000000000'):
#对base64解密再aes解密
data = base64.b64decode(data)
aescryptor = Aescrypt(passwd, AES.MODE_CBC, iv) # CBC模式
out = aescryptor.aesdecrypt_file(data)
return out
def encode(data,passwd = b"1234567812345678",iv = b'0000000000000000'):
#对字节型数据加密成aes,再base64
if type(data)==str:
data= data.encode()
aescryptor = Aescrypt(passwd, AES.MODE_CBC, iv) # CBC模式
out = aescryptor.aesencrypt_file(data)
out = base64.b64encode(out)
return out #bytes
# if __name__ == '__main__':
# passwd = b"1234567812345678"
# iv = b'1234567812345678'
# aescryptor = Aescrypt(passwd,AES.MODE_CBC,iv) # CBC模式
# text = b'sfdffd11111'
# print(len(text))
# en_text = aescryptor.aesencrypt(text)
# print("密文:",en_text)
#
# text = aescryptor.aesdecrypt(en_text)
# print("明文:",text)
使用方法把上面文件保存为cdde.py
然后创建一个test.py
import cdde
#a='ok'
a=b'\x01\x02\x03'
a1= cdde.encode(a)
print(a1)
a2 = cdde.decode(a1)
print(a2)
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网页标题:aes数据填充问题-创新互联
分享链接:http://scyanting.com/article/dccshs.html