Python实现AES加解密以及发送加解密请求


AES加解密的类

python解释器用的是3.9,安装Crypto相关模块报错的解决方案:
https://stackoverflow.com/questions/19623267/importerror-no-module-named-crypto-cipher

import base64
from binascii import b2a_hex, a2b_hex
from Crypto import Random
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad


class AESUtil(object):
    # 使用ECB模式加密
    MODE = AES.MODE_ECB
    # 使用默认的pkcs7 padding
    PAD_STYLE = 'pkcs7'
    ENCODING = 'UTF-8'

    # key长度只能为16或24或32,分别对应AES-128、AES-192、AES-256
    @staticmethod
    def encrypt(plaintext: str, key: str) -> str:
        # 将密钥编码为UTF-8格式的bytes
        key_bytes = key.encode(AESUtil.ENCODING)
        # 创建AES对象
        cipher = AES.new(key_bytes, AESUtil.MODE)
        # 将明文编码为UTF-8格式的bytes
        plaintext_bytes = plaintext.encode(AESUtil.ENCODING)
        # 为编码后的明文添加padding
        plaintext_bytes_padded = pad(plaintext_bytes, AES.block_size, AESUtil.PAD_STYLE)
        # 执行加密
        ciphertext_bytes = cipher.encrypt(plaintext_bytes_padded)
        # 将加密后的bytes进行base64编码
        # 注意:不能用encodebytes!否则会每76个字符增加一个换行符,见:https://docs.python.org/zh-cn/3/library/base64.html
        ciphertext_base64_bytes = base64.b64encode(ciphertext_bytes)
        # 将base64编码过的bytes,解码为Python中使用的字符串类型(即unicode字符串)
        ciphertext = ciphertext_base64_bytes.decode(AESUtil.ENCODING)
        return ciphertext

    @staticmethod
    def decrypt(ciphertext: str, key: str) -> str:
        # 将密钥编码为UTF-8格式的bytes
        key_bytes = key.encode(AESUtil.ENCODING)
        # 创建AES对象
        decrypter = AES.new(key_bytes, AESUtil.MODE)
        # 将密文编码为UTF-8格式的(同时也是base64编码的)bytes
        ciphertext_base64_bytes = ciphertext.encode(AESUtil.ENCODING)
        # 将base64编码的bytes,解码为原始的密文bytes
        ciphertext_bytes = base64.b64decode(ciphertext_base64_bytes)
        # 解码为明文
        plaintext_bytes_padded = decrypter.decrypt(ciphertext_bytes)
        # 去掉Padding
        plaintext_bytes = unpad(plaintext_bytes_padded, AES.block_size, AESUtil.PAD_STYLE)
        # 将UTF-8格式编码的明文bytes,解码为Python中的字符串类型(即unicode字符串)
        plaintext = plaintext_bytes.decode(AESUtil.ENCODING)
        return plaintext

class PrpCrypt(object):

    def __init__(self, key):
        self.key = key.encode('utf-8')
        self.mode = AES.MODE_CBC
        self.iv = Random.new().read(AES.block_size)

    # 加密函数,如果text不足16位就用空格补足为16位,
    # 如果大于16当时不是16的倍数,那就补足为16的倍数。
    def encrypt(self, text):
        text = text.encode('utf-8')
        cryptor = AES.new(self.key, self.mode, self.iv)
        # 这里密钥key 长度必须为16(AES-128),
        # 24(AES-192),或者32 (AES-256)Bytes 长度
        # 目前AES-128 足够目前使用
        length = 16
        count = len(text)
        if count < length:
            add = (length - count)
            # /0 backspace
            text = text + ('/0' * add).encode('utf-8')
        elif count > length:
            add = (length - (count % length))
            text = text + ('/0' * add).encode('utf-8')
        self.ciphertext = cryptor.encrypt(text)
        # 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
        # 所以这里统一把加密后的字符串转化为16进制字符串
        return b2a_hex(self.ciphertext)

    # 解密后,去掉补足的空格用strip() 去掉
    def decrypt(self, text):
        cryptor = AES.new(self.key, self.mode, self.iv)
        plain_text = cryptor.decrypt(a2b_hex(text))
        return bytes.decode(plain_text).rstrip('/0')



if __name__ == '__main__':
    aes_key = 'sbsbsbsbsbsbsbsb'
    pc = PrpCrypt(aes_key)  # 初始化密钥
    data = "xxx123"
    print("原始data: ", data)
    print("--------------第1种方法符合服务端的AES对称加密算法: ")
    e1 = AESUtil.encrypt(data, aes_key)
    d1 = AESUtil.decrypt(e1, aes_key)
    print("加密:", e1)
    print("解密:", d1)

    print("--------------第2种方法不符合服务端的AES对称加密算法: ")
    e2 = pc.encrypt(data)  # 加密
    d2 = pc.decrypt(e2).encode()  # 解密
    print("加密:", e2)
    print("解密:", d2)

    """
        原始data:  xxx123
        --------------第1种方法符合服务端的AES对称加密算法: 
        加密: fRpmp7q6laM5A96Nr/ZyPA==
        解密: xxx123
        --------------第2种方法不符合服务端的AES对称加密算法: 
        加密: b'8efdb7c72cd323ee204e2f290e6becd5'
        解密: b'xxx123'
    """

发动加密的post请请求

666

 

原创文章,作者:carmelaweatherly,如若转载,请注明出处:https://blog.ytso.com/274289.html

(0)
上一篇 2022年7月14日
下一篇 2022年7月14日

相关推荐

发表回复

登录后才能评论