python实现AES加解密功能

关于加密方式、编码和字符集的说明:

安装库

# 一个Python的加密库,提供了各种加密算法,包括AES。
sudo pip3 install pycrypto

 代码实现

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
"""
AES:
AES加密算法的密钥长度必须是16、24或32字节(128、192或256位)。这些长度分别对应AES-128、AES-192和AES-256。16位够用了。
明文的长度必须是AES块大小的整数倍.
IV的长度必须等于AES的块大小.
print(AES.block_size)   # 16
"""
from Crypto import Random
from Crypto.Cipher import AES
import base64


class aescrypt():
    def __init__(self, key, model, iv, encode_='utf8'):
        """
        key : byte string 用于对称加密的密钥。
        iv: byte string  用于加密或解密的初始化向量。mode是ECB时忽略IV
        """
        self.encode_ = encode_
        # key传参不要超过16位,因为它必须是16位,add_to_16方法其实是补充至16的倍数,这里注意下
        self.key = self.add_to_16(key)
        self.iv = iv

        if model == 'ECB':
            self.model = AES.MODE_ECB
            # 创建一个aes对象,mode默认是ECB
            self.aes = AES.new(self.key, mode=AES.MODE_ECB)
        elif model == 'CFB':
            self.model = AES.MODE_CFB
            # 创建一个aes对象
            self.aes = AES.new(self.key, mode=AES.MODE_CFB, IV=self.iv)

    def add_to_16(self, par):
        # 先将字符串类型数据转换成字节型数据,默认按utf-8编码,中文占3个字节(gbk编码占2个字节)
        par = par.encode(self.encode_)
        # 对字节型数据进行长度判断,如果字节型数据长度不是16倍整数就进行补充
        while len(par) % 16 != 0:
            par += b'\x00'
        return par

    def aesencrypt(self, plaintext):
        """
        plaintext : byte string
        """
        # 将明文补齐为16字节的倍数
        text = self.add_to_16(plaintext)
        # 调用加密方法,这个方法返回的数据类型是bytes
        encrypt_text = self.aes.encrypt(text)
        # 返回base64编码后的bytes数据或再进一步进行utf8解码的str数据
        # print(encrypt_text.decode(self.encode_))  # 这个直接utf8解码会报错,所以得先进行base64编码
        # return base64.encodebytes(encrypt_text)
        return base64.encodebytes(encrypt_text).decode(self.encode_).strip()

    def aesdecrypt(self, text):
        # 先对要解密的文本作对应的处理,这里对应于aesencrypt方法中的加密数据的处理
        # text = base64.decodebytes(text)
        text = base64.decodebytes(text.encode(self.encode_))
        # 即使在__init__方法中已经创建了self.aes对象,但在CFB模式下,每次加密和解密时都需要重新初始化self.aes对象,以确保使用正确的IV。这是因为CFB模式依赖于IV来生成密钥流,而这个密钥流用于加密和解密数据。
        if self.model == AES.MODE_CFB:
            self.aes = AES.new(self.key, mode=self.model, IV=self.iv)
        # 调用解密方法
        decrypt_text = self.aes.decrypt(text)
        # 解密后的bytes类型还需要解码为str
        return decrypt_text.strip(b'\x00').decode(self.encode_)


if __name__ == '__main__':
    # 加密
    key = 'this is key'
    # iv通过方法生成,bytes类型
    iv = Random.new().read(AES.block_size)
    print(iv)
    # 初始化aescrypt类
    pr = aescrypt(key, 'CFB', iv)
    # 对content加密
    content = '我是要加密的内容'
    en_text = pr.aesencrypt(content)
    print('密文:', en_text)
    # 对加密后的密文解密
    print('明文:', pr.aesdecrypt(en_text))


"""
b'\xaf\x96\xec\x810x\xa9\xee;\xc0\x82TM\xc5 \x11'
密文: VBmZmgiINYON81jTRceT21h5fseIk5ZDkG0kc/fGHiQ=
明文: 我是要加密的内容
"""

密码学是一个很大很广的方向,我等任重而道远~

推荐博文

字符集(charset)与编码(encoding)区别对比-****博客 

字符集和字符编码(Charset & Encoding)-****博客

[一文详解]Base64编码,Url Base64编码,UrlEncode编码,你还傻傻分不清吗?-****博客

python常见的加密方式-****博客

gpg使用方法_gpg -r $user-****博客

openssl ecc和rsa密钥对以及证书生成_openssl生成ecc密钥-****博客

上一篇:粉丝生产力与开源 AI 智能名片 2+1 链动模式商城小程序的融合创新与价值拓展


下一篇:IEEE T-RO 软体机器人手指状态估计实现两栖触觉传感