#encoding:utf8 import base64 from Crypto.Cipher import AES from Crypto import Random import pandas as pd class AESCipher: def __init__(self): ''' CBC加密需要一个十六位的key(密钥)和一个十六位iv(偏移量) ''' self.key = self.check_key(base64.b64decode('zDXjL5mx5HeUgmsg7HyKLg==') ) # 数据块的大小 16位 self.BS = 32 # CBC模式 相对安全 因为有偏移向量 iv 也是16位字节的 self.mode = AES.MODE_ECB # 填充函数 因为AES加密是一段一段加密的 每段都是BS位字节,不够的话是需要自己填充的 self.pad = lambda s: s + (self.BS - len(s.encode()) % self.BS)*chr(self.BS - len(s.encode()) % self.BS) # 将填充的数据剔除 self.unpad = lambda s: s[:-ord(s[len(s) - 1:])] def check_key(self, key): ''' 检测key的长度是否为16,24或者32bytes的长度 ''' try: if isinstance(key, bytes): assert len(key) in [16, 24, 32] return key elif isinstance(key, str): assert len(key.encode()) in [16, 24, 32] return key.encode() else: raise Exception('密钥必须为str或bytes,不能为%s'%type(key)) except AssertionError: print('输入的长度不正确') def check_data(self, data): ''' 检测加密的数据类型 ''' if isinstance(data, int): data = str(data) elif isinstance(data, bytes): data = data.decode() elif isinstance(data, str): pass else: raise Exception('加密的数据必须为str或bytes,不能为%s'%type(data)) return data def text2hex(self,_str): list_hex = [] if isinstance(_str,str): _str1 = _str.encode() elif isinstance(_str,bytes): _str1 = _str for _hex in map(hex,_str1): _i = int(_hex[2:],16) while(True): a = _i&0xFF list_hex.append(hex(a)[2:].rjust(2,"0")) _i = _i >>8 if _i==0: break return "".join(list_hex) def encrypt(self, raw): raw = self.check_data(raw) raw = self.pad(raw).encode() # 随机获取iv iv = Random.new().read(AES.block_size) # 定义初始化 cipher = AES.new(self.key, self.mode) # 此处是将密文和iv一起 base64 解密的时候就可以根据这个iv来解密 return self.text2hex(cipher.encrypt(raw)) return base64.b64encode(cipher.encrypt(raw)).decode() def decrypt(self, enc): # 先将密文进行base64解码 enc = base64.b64decode(enc) # 取出iv值 iv = enc[:self.BS] # 初始化自定义 cipher = AES.new(self.key, self.mode, iv) # 返回utf8格式的数据 return self.unpad(cipher.decrypt(enc[self.BS:])).decode() aesCipher = AESCipher()