可算搞成一半了,经核对,加解密后哈希值相等,可以正常使用
# 二进制加密解密测试完成 import base64 import hashlib import os from Crypto.Cipher import AES from Crypto import Random """ 神坑: 将crypto的包文件夹改成大写即可, 或者安装pycryptodome 在 Windows 中,不管是 Python2 和 Python3 ,都不能用 crypto 和 pycrypto ,可以用 pycryptodome 。 在 Linux 中,不管是 Python2 和 Python3 ,都不能用 crypto ,可以用 pycrypto 和 pycryptodome 。 还要安装cipher """ with open(file='C:/log2.txt',mode='r',encoding='utf-8') as f: secret = f.read() print(secret) class AESCipher: def __init__(self): ''' CBC加密需要一个十六位的key(密钥)和一个十六位iv(偏移量) ''' self.key = self.check_key(secret) # 数据块的大小 16位 self.BS = 16 # CBC模式 相对安全 因为有偏移向量 iv 也是16位字节的 self.mode = AES.MODE_CBC # 填充函数 因为AES加密是一段一段加密的 每段都是BS位字节,不够的话是需要自己填充的 self.pad = lambda s: s + ((self.BS - len(s) % self.BS)*chr(self.BS - len(s) % self.BS)).encode() # 将填充的数据剔除 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: pass # raise Exception(f'密钥必须为str或bytes,不能为{type(key)}') except AssertionError: print('输入的长度不正确') def check_data(self, data): ''' 检测加密的数据类型 ''' if isinstance(data, int): data = str(data) elif isinstance(data, bytes): # data = data.decode() data = data # 改字节加解密不需要这个 elif isinstance(data, str): pass else: pass # raise Exception(f'加密的数据必须为str或bytes,不能为{type(data)}') return data def encrypt(self, raw): raw = self.check_data(raw) print('lenchecked raw',len(raw)) raw = self.pad(raw) #改字节加密,注释此句 print('len pad rawlen',len(raw)) # 随机获取iv iv = Random.new().read(AES.block_size) # 定义初始化 cipher = AES.new(self.key, self.mode, iv) # 此处是将密文和iv一起 base64 解密的时候就可以根据这个iv来解密 encdata = iv + cipher.encrypt(raw) print('len enc data',len(encdata)) return encdata def decrypt(self, enc): # 先将密文进行base64解码 # enc = base64.b64decode(enc) #加密不存base64了, 后面直接用二进制 可节省空间30% # 取出iv值 iv = enc[:self.BS] # 初始化自定义 cipher = AES.new(self.key, self.mode, iv) # 返回utf8格式的数据 return self.unpad(cipher.decrypt(enc[self.BS:])) #删除decode()保留二进制写入 # from random import randint if __name__ == "__main__": encpython = r'C:\Users\Administrator\Desktop\加密' files = os.walk(encpython) for path,dirlist,filelist in files: for file in filelist: if not file.startswith('enc777'): file_path = os.path.join(path, file) with open(file=os.path.join(path,file),mode='rb') as f: file_content = f.read() content_hash = hashlib.md5(file_content).hexdigest() aes = AESCipher() enc_content = aes.encrypt(file_content) dec_contnet = aes.decrypt(enc_content) content_hashdec = hashlib.md5(dec_contnet).hexdigest() print(content_hash==content_hashdec,'ddddd')