SymmetricCryptoUtil.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. from Crypto.Cipher import AES
  2. import base64
  3. import binascii
  4. # 数据类
  5. class MData:
  6. def __init__(self, data=b"", characterSet='utf-8'):
  7. # data肯定为bytes
  8. self.data = data
  9. self.characterSet = characterSet
  10. def saveData(self, FileName):
  11. with open(FileName, 'wb') as f:
  12. f.write(self.data)
  13. def fromString(self, data):
  14. self.data = data.encode(self.characterSet)
  15. return self.data
  16. def fromBase64(self, data):
  17. self.data = base64.b64decode(data.encode(self.characterSet))
  18. return self.data
  19. def fromHexStr(self, data):
  20. self.data = binascii.a2b_hex(data)
  21. return self.data
  22. def toString(self):
  23. return self.data.decode(self.characterSet)
  24. def toBase64(self):
  25. return base64.b64encode(self.data).decode()
  26. def toHexStr(self):
  27. return binascii.b2a_hex(self.data).decode()
  28. def toBytes(self):
  29. return self.data
  30. def __str__(self):
  31. try:
  32. return self.toString()
  33. except Exception:
  34. return self.toBase64()
  35. """
  36. 封装类
  37. """
  38. class AESencrypt:
  39. def __init__(self, encode_key, mode, iv_key=b'', paddingMode="NoPadding", characterSet="utf-8"):
  40. """
  41. 构建一个AES对象
  42. key: 秘钥,字节型数据
  43. mode: 使用模式,只提供两种,AES.MODE_CBC, AES.MODE_ECB
  44. iv: iv偏移量,字节型数据
  45. paddingMode: 填充模式,默认为NoPadding, 可选NoPadding,ZeroPadding,PKCS5Padding,PKCS7Padding
  46. characterSet: 字符集编码
  47. """
  48. self.key = encode_key
  49. self.mode = mode
  50. self.iv = iv_key
  51. self.characterSet = characterSet
  52. self.paddingMode = paddingMode
  53. self.data = ""
  54. @classmethod
  55. def __zero_padding(cls, data):
  56. data += b'\x00'
  57. while len(data) % 16 != 0:
  58. data += b'\x00'
  59. return data
  60. @classmethod
  61. def __strip_zero_padding(cls, data):
  62. data = data[:-1]
  63. while len(data) % 16 != 0:
  64. data = data.rstrip(b'\x00')
  65. if data[-1] != b"\x00":
  66. break
  67. return data
  68. def __PKCS5_7Padding(self, data):
  69. needSize = 16 - len(data) % 16
  70. if needSize == 0:
  71. needSize = 16
  72. return data + needSize.to_bytes(1, 'little') * needSize
  73. def __StripPKCS5_7Padding(self, data):
  74. paddingSize = data[-1]
  75. return data.rstrip(paddingSize.to_bytes(1, 'little'))
  76. def __paddingData(self, data):
  77. if self.paddingMode == "NoPadding":
  78. if len(data) % 16 == 0:
  79. return data
  80. else:
  81. return self.__zero_padding(data)
  82. elif self.paddingMode == "ZeroPadding":
  83. return self.__zero_padding(data)
  84. elif self.paddingMode == "PKCS5Padding" or self.paddingMode == "PKCS7Padding":
  85. return self.__PKCS5_7Padding(data)
  86. else:
  87. print("不支持Padding")
  88. def __stripPaddingData(self, data):
  89. if self.paddingMode == "NoPadding":
  90. return self.__strip_zero_padding(data)
  91. elif self.paddingMode == "ZeroPadding":
  92. return self.__strip_zero_padding(data)
  93. elif self.paddingMode == "PKCS5Padding" or self.paddingMode == "PKCS7Padding":
  94. return self.__StripPKCS5_7Padding(data)
  95. else:
  96. print("不支持Padding")
  97. def setCharacterSet(self, characterSet):
  98. """
  99. 设置字符集编码
  100. characterSet: 字符集编码
  101. """
  102. self.characterSet = characterSet
  103. def setPaddingMode(self, mode):
  104. """
  105. 设置填充模式
  106. mode: 可选NoPadding,ZeroPadding,PKCS5Padding,PKCS7Padding
  107. """
  108. self.paddingMode = mode
  109. def decryptFromBase64(self, entext):
  110. """
  111. 从base64编码字符串编码进行AES解密
  112. entext: 数据类型str
  113. """
  114. mData = MData(characterSet=self.characterSet)
  115. self.data = mData.fromBase64(entext)
  116. return self.__decrypt()
  117. def decryptFromHexStr(self, entext):
  118. """
  119. 从hexstr编码字符串编码进行AES解密
  120. entext: 数据类型str
  121. """
  122. mData = MData(characterSet=self.characterSet)
  123. self.data = mData.fromHexStr(entext)
  124. return self.__decrypt()
  125. def decryptFromString(self, entext):
  126. """
  127. 从字符串进行AES解密
  128. entext: 数据类型str
  129. """
  130. mData = MData(characterSet=self.characterSet)
  131. self.data = mData.fromString(entext)
  132. return self.__decrypt()
  133. def decryptFromBytes(self, entext):
  134. """
  135. 从二进制进行AES解密
  136. entext: 数据类型bytes
  137. """
  138. self.data = entext
  139. return self.__decrypt()
  140. def encryptFromString(self, data):
  141. """
  142. 对字符串进行AES加密
  143. data: 待加密字符串,数据类型为str
  144. """
  145. self.data = data.encode(self.characterSet)
  146. return self.__encrypt()
  147. def __encrypt(self):
  148. """
  149. 加密数据
  150. @return:
  151. """
  152. if self.mode == AES.MODE_CBC:
  153. aes = AES.new(self.key, self.mode, self.iv)
  154. elif self.mode == AES.MODE_ECB:
  155. aes = AES.new(self.key, self.mode)
  156. else:
  157. print("不支持这种模式")
  158. return
  159. data = self.__paddingData(self.data)
  160. enData = aes.encrypt(data)
  161. return MData(enData)
  162. def __decrypt(self):
  163. if self.mode == AES.MODE_CBC:
  164. aes = AES.new(self.key, self.mode, self.iv)
  165. elif self.mode == AES.MODE_ECB:
  166. aes = AES.new(self.key, self.mode)
  167. else:
  168. print("不支持这种模式")
  169. return
  170. data = aes.decrypt(self.data)
  171. mData = MData(self.__stripPaddingData(data), characterSet=self.characterSet)
  172. return mData
  173. if __name__ == '__main__':
  174. key = b"1234567812345678"
  175. iv = b"0000000000000000"
  176. aes = AESencrypt(key, AES.MODE_CBC, iv, paddingMode="ZeroPadding", characterSet='utf-8')
  177. str_data = "dddd321123."
  178. rData = aes.encryptFromString(str_data)
  179. print("加密:", rData.toBase64())
  180. rData = aes.decryptFromBase64(rData.toBase64())
  181. print("解密:", rData)