|
|
@ -1,33 +1,29 @@
|
|
|
|
# "ecb", "cbc", "cfb", "ofb"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from Crypto.Cipher import AES
|
|
|
|
from Crypto.Cipher import AES
|
|
|
|
from Crypto.Util.Padding import pad, unpad
|
|
|
|
from Crypto.Util.Padding import pad, unpad
|
|
|
|
from Crypto.Random import get_random_bytes
|
|
|
|
from Crypto.Random import get_random_bytes
|
|
|
|
import base64
|
|
|
|
import base64
|
|
|
|
from fontTools.misc.eexec import encrypt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AESUtils:
|
|
|
|
class AESUtils:
|
|
|
|
def __init__(self, key: bytes = None):
|
|
|
|
def __init__(self, key: bytes = None):
|
|
|
|
"""生成一个随机密钥"""
|
|
|
|
"""生成一个随机密钥"""
|
|
|
|
self.key = get_random_bytes(32)
|
|
|
|
self.key = key if key else get_random_bytes(16)
|
|
|
|
|
|
|
|
|
|
|
|
def encrypt(self, data: str, mode: str = 'ECB') -> (str,str):
|
|
|
|
def encrypt(self, data1: str, mode: str = 'ECB') -> (str, str):
|
|
|
|
"""加密数据"""
|
|
|
|
"""加密数据"""
|
|
|
|
cipher = self._get_cipher(mode)
|
|
|
|
cipher = self._get_encipher(mode)
|
|
|
|
data = pad(data.encode(), AES.block_size) # 填充数据
|
|
|
|
data1 = pad(data1.encode('utf-8'), AES.block_size) # 填充数据
|
|
|
|
ciphertext = cipher.encrypt(data)
|
|
|
|
ciphertext = cipher.encrypt(data1)
|
|
|
|
return base64.b64encode(ciphertext).decode(), self.key
|
|
|
|
return base64.b64encode(ciphertext).decode('utf-8'), self.key
|
|
|
|
|
|
|
|
|
|
|
|
def decrypt(self, encrypted_data: str, mode: str = 'ECB') -> str:
|
|
|
|
def decrypt(self, dekey, encrypted_data: str, mode: str = 'ECB') -> str:
|
|
|
|
"""解密数据"""
|
|
|
|
"""解密数据"""
|
|
|
|
cipher = self._get_cipher(mode)
|
|
|
|
cipher = self._get_decipher(dekey, mode)
|
|
|
|
encrypted_data = base64.b64decode(encrypted_data)
|
|
|
|
encrypted_data = base64.b64decode(encrypted_data) # 解码密文
|
|
|
|
plaintext = unpad(cipher.decrypt(encrypted_data), AES.block_size)
|
|
|
|
plaintext = unpad(cipher.decrypt(encrypted_data), AES.block_size)
|
|
|
|
return plaintext.decode()
|
|
|
|
return plaintext.decode()
|
|
|
|
|
|
|
|
|
|
|
|
def _get_cipher(self, mode: str) -> AES:
|
|
|
|
def _get_encipher(self, mode: str) -> AES:
|
|
|
|
"""根据模式返回相应的 AES cipher"""
|
|
|
|
"""根据模式返回相应的加密 AES cipher"""
|
|
|
|
iv = None
|
|
|
|
iv = None
|
|
|
|
if mode == 'CBC':
|
|
|
|
if mode == 'CBC':
|
|
|
|
iv = get_random_bytes(AES.block_size)
|
|
|
|
iv = get_random_bytes(AES.block_size)
|
|
|
@ -39,12 +35,29 @@ class AESUtils:
|
|
|
|
else: # 默认是 ECB
|
|
|
|
else: # 默认是 ECB
|
|
|
|
return AES.new(self.key, AES.MODE_ECB)
|
|
|
|
return AES.new(self.key, AES.MODE_ECB)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
def _get_decipher(self, dekey, mode: str) -> AES:
|
|
|
|
# 示例数据和密钥
|
|
|
|
"""根据模式返回相应的解密 AES cipher"""
|
|
|
|
data = "Hello, SM4!"
|
|
|
|
iv = None
|
|
|
|
key = "1234567890abcdef"
|
|
|
|
if mode == 'CBC':
|
|
|
|
|
|
|
|
iv = get_random_bytes(AES.block_size)
|
|
|
|
|
|
|
|
return AES.new(dekey, AES.MODE_CBC, iv)
|
|
|
|
|
|
|
|
elif mode == 'CFB':
|
|
|
|
|
|
|
|
return AES.new(dekey, AES.MODE_CFB)
|
|
|
|
|
|
|
|
elif mode == 'OFB':
|
|
|
|
|
|
|
|
return AES.new(dekey, AES.MODE_OFB)
|
|
|
|
|
|
|
|
else: # 默认是 ECB
|
|
|
|
|
|
|
|
return AES.new(dekey, AES.MODE_ECB)
|
|
|
|
|
|
|
|
|
|
|
|
enData , akey = AESUtils(key)
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
|
|
|
key = b'1234567890abcdef' # AES 密钥必须是 16 字节
|
|
|
|
|
|
|
|
aes = AESUtils(key)
|
|
|
|
|
|
|
|
|
|
|
|
print(enData)
|
|
|
|
# 加密
|
|
|
|
|
|
|
|
plaintext = "Hello, AES!"
|
|
|
|
|
|
|
|
enData, akey = aes.encrypt(plaintext, mode='ECB')
|
|
|
|
|
|
|
|
print("Encrypted Data:", enData)
|
|
|
|
|
|
|
|
print("Key:", akey)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 解密
|
|
|
|
|
|
|
|
decrypted = aes.decrypt(aes.key, enData, mode='ECB')
|
|
|
|
|
|
|
|
print("Decrypted:", decrypted)
|