-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathaes_model.py
More file actions
217 lines (179 loc) · 6.6 KB
/
aes_model.py
File metadata and controls
217 lines (179 loc) · 6.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# -*- coding: utf-8 -*-
# python 在 Windows/Linux/macOS下使用AES时要安装的是pycryptodomex模块
# 查了官方文档发现已经版本更新,需要下载最新包,如下命令
# pip3 install pycryptodomex
# 下载成功后,使用from Cryptodome.Cipher import AES,即可使用
# 以上是网上找的教程,但是在我的电脑(macos)上,使用pip install pycryptodome==3.15.0,安装成功后,使用from Crypto.Cipher import AES,即可使用。
from Crypto.Cipher import AES
import base64
import binascii
# 数据类
class MData(object):
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 AEScryptor(object):
def __init__(self, key, mode=AES.MODE_CBC, iv='', 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 = key.encode(characterSet)
self.mode = mode
self.iv = iv.encode(characterSet)
self.characterSet = characterSet
self.paddingMode = paddingMode
self.data = ""
def __ZeroPadding(self, data):
data += b'\x00'
while len(data) % 16 != 0:
data += b'\x00'
return data
def __StripZeroPadding(self, 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.__ZeroPadding(data)
elif self.paddingMode == "ZeroPadding":
return self.__ZeroPadding(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.__StripZeroPadding(data)
elif self.paddingMode == "ZeroPadding":
return self.__StripZeroPadding(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):
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 = 'vqwn3p22uics8xv8' # 16位
iv = 's0Q~ioZ(AYJxyvLQ' # 16位
aes = AEScryptor(key=key, iv=iv, paddingMode='ZeroPadding', characterSet='utf-8')
data = '好好学习111!@#$%^&*()_+'
rData = aes.encryptFromString(data)
print('密文:', rData.toBase64())
rData = aes.decryptFromBase64(rData.toBase64())
print('明文:', rData)