123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- from Crypto.Cipher import AES
- import base64
- import binascii
- # 数据类
- class MData:
- def __init__(self, data=b"", characterSet='utf-8'):
- # data肯定为bytes
- self.data = data
- self.characterSet = characterSet
- def saveData(self, FileName):
- with open(FileName, 'wb') as f:
- f.write(self.data)
- def fromString(self, data):
- self.data = data.encode(self.characterSet)
- return self.data
- def fromBase64(self, data):
- self.data = base64.b64decode(data.encode(self.characterSet))
- return self.data
- def fromHexStr(self, data):
- self.data = binascii.a2b_hex(data)
- return self.data
- def toString(self):
- return self.data.decode(self.characterSet)
- def toBase64(self):
- return base64.b64encode(self.data).decode()
- def toHexStr(self):
- return binascii.b2a_hex(self.data).decode()
- def toBytes(self):
- return self.data
- def __str__(self):
- try:
- return self.toString()
- except Exception:
- return self.toBase64()
- """
- 封装类
- """
- class AESencrypt:
- def __init__(self, encode_key, mode, iv_key=b'', paddingMode="NoPadding", characterSet="utf-8"):
- """
- 构建一个AES对象
- key: 秘钥,字节型数据
- mode: 使用模式,只提供两种,AES.MODE_CBC, AES.MODE_ECB
- iv: iv偏移量,字节型数据
- paddingMode: 填充模式,默认为NoPadding, 可选NoPadding,ZeroPadding,PKCS5Padding,PKCS7Padding
- characterSet: 字符集编码
- """
- self.key = encode_key
- self.mode = mode
- self.iv = iv_key
- self.characterSet = characterSet
- self.paddingMode = paddingMode
- self.data = ""
- @classmethod
- def __zero_padding(cls, data):
- data += b'\x00'
- while len(data) % 16 != 0:
- data += b'\x00'
- return data
- @classmethod
- def __strip_zero_padding(cls, data):
- data = data[:-1]
- while len(data) % 16 != 0:
- data = data.rstrip(b'\x00')
- if data[-1] != b"\x00":
- break
- return data
- def __PKCS5_7Padding(self, data):
- needSize = 16 - len(data) % 16
- if needSize == 0:
- needSize = 16
- return data + needSize.to_bytes(1, 'little') * needSize
- def __StripPKCS5_7Padding(self, data):
- paddingSize = data[-1]
- return data.rstrip(paddingSize.to_bytes(1, 'little'))
- def __paddingData(self, data):
- if self.paddingMode == "NoPadding":
- if len(data) % 16 == 0:
- return data
- else:
- return self.__zero_padding(data)
- elif self.paddingMode == "ZeroPadding":
- return self.__zero_padding(data)
- elif self.paddingMode == "PKCS5Padding" or self.paddingMode == "PKCS7Padding":
- return self.__PKCS5_7Padding(data)
- else:
- print("不支持Padding")
- def __stripPaddingData(self, data):
- if self.paddingMode == "NoPadding":
- return self.__strip_zero_padding(data)
- elif self.paddingMode == "ZeroPadding":
- return self.__strip_zero_padding(data)
- elif self.paddingMode == "PKCS5Padding" or self.paddingMode == "PKCS7Padding":
- return self.__StripPKCS5_7Padding(data)
- else:
- print("不支持Padding")
- def setCharacterSet(self, characterSet):
- """
- 设置字符集编码
- characterSet: 字符集编码
- """
- self.characterSet = characterSet
- def setPaddingMode(self, mode):
- """
- 设置填充模式
- mode: 可选NoPadding,ZeroPadding,PKCS5Padding,PKCS7Padding
- """
- self.paddingMode = mode
- def decryptFromBase64(self, entext):
- """
- 从base64编码字符串编码进行AES解密
- entext: 数据类型str
- """
- mData = MData(characterSet=self.characterSet)
- self.data = mData.fromBase64(entext)
- return self.__decrypt()
- def decryptFromHexStr(self, entext):
- """
- 从hexstr编码字符串编码进行AES解密
- entext: 数据类型str
- """
- mData = MData(characterSet=self.characterSet)
- self.data = mData.fromHexStr(entext)
- return self.__decrypt()
- def decryptFromString(self, entext):
- """
- 从字符串进行AES解密
- entext: 数据类型str
- """
- mData = MData(characterSet=self.characterSet)
- self.data = mData.fromString(entext)
- return self.__decrypt()
- def decryptFromBytes(self, entext):
- """
- 从二进制进行AES解密
- entext: 数据类型bytes
- """
- self.data = entext
- return self.__decrypt()
- def encryptFromString(self, data):
- """
- 对字符串进行AES加密
- data: 待加密字符串,数据类型为str
- """
- self.data = data.encode(self.characterSet)
- return self.__encrypt()
- def __encrypt(self):
- """
- 加密数据
- @return:
- """
- if self.mode == AES.MODE_CBC:
- aes = AES.new(self.key, self.mode, self.iv)
- elif self.mode == AES.MODE_ECB:
- aes = AES.new(self.key, self.mode)
- else:
- print("不支持这种模式")
- return
- data = self.__paddingData(self.data)
- enData = aes.encrypt(data)
- return MData(enData)
- def __decrypt(self):
- if self.mode == AES.MODE_CBC:
- aes = AES.new(self.key, self.mode, self.iv)
- elif self.mode == AES.MODE_ECB:
- aes = AES.new(self.key, self.mode)
- else:
- print("不支持这种模式")
- return
- data = aes.decrypt(self.data)
- mData = MData(self.__stripPaddingData(data), characterSet=self.characterSet)
- return mData
- if __name__ == '__main__':
- key = b"1234567812345678"
- iv = b"0000000000000000"
- aes = AESencrypt(key, AES.MODE_CBC, iv, paddingMode="ZeroPadding", characterSet='utf-8')
- str_data = "dddd321123."
- rData = aes.encryptFromString(str_data)
- print("加密:", rData.toBase64())
- rData = aes.decryptFromBase64(rData.toBase64())
- print("解密:", rData)
|