Python实现aes加密解密多种方法解析
引子:
在windows中python3使用pycryptodemo模块实现Aes加密解密。Aes加密有多种方式,自己可以上网了解下。AES是每16位一加密,并且保证key和vi都是16位的。废话不多说直接上代码。
importbase64 fromCrypto.CipherimportAES frombinasciiimportb2a_hex,a2b_hex classPrpCrypt(object): def__init__(self,key,iv): self.key=key.encode('utf-8') self.mode=AES.MODE_CBC self.iv=iv.encode('utf-8') defpad_byte(self,b): ''' 1先计算所传入bytes类型文本与16的余数 2在将此余数转成bytes当然用0补位也可以 3已知了余数那么就用余数*被转成的余数,就得到了需要补全的bytes 4拼接原有文本和补位 :paramb:bytes类型的文本 :return:返回补全后的bytes文本 ''' bytes_num_to_pad=AES.block_size-(len(b)%AES.block_size) #python3中默认unicode转码 #实际上byte_to_pad就已经将数字转成了unicode对应的字符即使你的入参正好是16的倍数,那么bytes也是把列表整体的转码也是有值的 #后边解密的匿名函数拿到最后一个数字后,就知道应该截取的长度,在反着切片就行了 #这样保证了数据的完整性 byte_to_pad=bytes([bytes_num_to_pad]) padding=byte_to_pad*bytes_num_to_pad padded=b+padding returnpadded defencrypt(self,text): ''' 1先生成aes实例 2对传入的text转成bytes 3对传入的text补全 4调用encrypt加密得到密文 5先将密文转16进制,在将16进制用base64转码,然后在将得到的base64解码 其实在步骤4就已经完成了aes加密,我所在的公司加密比较复杂,需要的可以直接返回步骤4的值 :paramtext: :return: ''' cryptor=AES.new(self.key,self.mode,self.iv) text=text.encode('utf-8') text=self.pad_byte(text) self.ciphertext=cryptor.encrypt(text) cryptbase64=base64.b64encode(b2a_hex(self.ciphertext)).decode('utf8') returncryptbase64 defdecrypt(self,text): ''' 解密和加密的顺序是相反的 1定义匿名函数,去掉补位 2base64解码 3生成aes实例 416进制转2进制 5使用decrypt解码得到补全的bytes类型明文 :paramtext: :return:解密且去掉补位的明文 ''' unpad=lambdas:s[:-ord(s[len(s)-1:])] base64Str=base64.b64decode(text.encode('utf8')) cryptor=AES.new(self.key,self.mode,self.iv) aesStr=cryptor.decrypt(a2b_hex(base64Str)) aesStr=str(unpad(aesStr),encoding='utf8') returnaesStr if__name__=='__main__': data='sadfsasdgsdfgdsf123' pc=PrpCrypt('daajanbaqa654321','1234567890123456') redata=pc.encrypt(data) print(redata) result=pc.decrypt(redata) print(result)
思路:
这里引用一句前辈的话,思路很重要。具体的怎么实现反而在其次。
1因为Aes是按照16位加密的,key和iv都好说,可以直接设置成定长的16位。
2因为传入的数据和传回的数据不是定长的,所以加密的时候要先判断是否是16位的倍数,如果不够那么就补全。
3问题是对端拿到数据后怎么知道从哪里截取。
1在对传入数据做是否16位判断的时候,你就知道了要补多少位,将这个数字转成bytes类型,python3中默认unicode码。
2对端拿到数据后,先截取最后一位,在根据unicode转成对应数字,那么对端就知道了从哪开始截取。
3看下unicode和utf8的关系,utf8是unicode实现的一种方式
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。