forked from limoruirui/misaka
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaes_encrypt.py
49 lines (49 loc) · 2.39 KB
/
aes_encrypt.py
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
#!/usr/bin/python3
# -- coding: utf-8 --
# -------------------------------
# @Author : github@limoruirui https://github.com/limoruirui
# @Time : 2022/8/22 18:13
# -------------------------------
"""
aes加密解密工具 目前仅支持ECB/CBC 块长度均为128位 padding只支持pkcs7/zero_padding(aes中没有pkcs5 能用的pkcs5其实是执行的pkcs7) 后续有需要再加
pycryptdemo限制 同一个aes加密对象不能即加密又解密 所以当加密和解密都需要执行时 需要重新new一个对象增加额外开销
-- A cipher object is stateful: once you have encrypted a message , you cannot encrypt (or decrypt) another message using the same object.
"""
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
from base64 import b64encode, b64decode
class AES_Ctypt:
def __init__(self, key, iv=None, mode="ECB"):
if len(key) % 16 != 0:
key = key + (AES.block_size - len(key) % AES.block_size) * chr(0)
self.key = key.encode("utf-8")
if mode == "ECB":
self.mode = AES.MODE_ECB
elif mode == "CBC":
self.mode = AES.MODE_CBC
else:
print("您选择的加密方式错误")
if iv is None:
self.cipher = AES.new(self.key, self.mode)
else:
if isinstance(iv, str):
self.cipher = AES.new(self.key, self.mode, iv.encode("utf-8"))
else:
print("偏移量不为字符串")
def encrypt(self, data, padding="pkcs7", b64=False):
bs = AES.block_size
pkcs7_padding = lambda s: s + (bs - len(s.encode()) % bs) * chr(bs - len(s.encode()) % bs)
zero_padding = lambda s: s + (bs - len(s) % bs) * chr(0)
pad = pkcs7_padding if padding=="pkcs7" else zero_padding
data = self.cipher.encrypt(pad(data).encode("utf8"))
encrypt_data = b64encode(data) if b64 else b2a_hex(data) # 输出hex或者base64
return encrypt_data.decode('utf8')
def decrypt(self, data, b64=False):
data = b64decode(data) if b64 else a2b_hex(data)
decrypt_data = self.cipher.decrypt(data).decode()
# 去掉padding
# pkcs7_unpadding = lambda s: s.replace(s[-1], "")
# zero_unpadding = lambda s: s.replace(chr(0), "")
# unpadding = pkcs7_unpadding if padding=="pkcs7" else zero_unpadding
unpadding = lambda s: s.replace(s[-1], "")
return unpadding(decrypt_data)