Python实现AES加密解密:ECB/CBC模式与PKCS7填充详解
本文详细介绍Python中AES高级加密标准的实现方法,涵盖ECB与CBC两种常用加密模式的区别,以及PKCS7填充算法的原理。通过面向对象代码示例,解析AES-128/192/256密钥长度对安全性的影响,并对比Java中PKCS5Padding与PKCS7的关系,帮助开发者掌握对称加密的核心技术。
AES加密模式概述
一、前言
AES(Advanced Encryption Standard,高级加密标准)是目前广泛使用的对称加密算法,旨在替代已不再安全的DES算法。与之前文章介绍的RSA非对称加密不同,AES仅使用单一密钥,该密钥同时承担加密和解密的任务。
AES作为基础算法,支持多种工作模式,主要包括ECB、CBC、CFB和OFB(此外还有CTR模式)。不同模式在数据处理方式和安全性上各有特点。
1. ECB模式(电子密码本模式:Electronic Codebook)
ECB是最基础的块加密模式。加密时,先将明文按块大小(如AES为128位)分割成若干块,随后使用相同的密钥对每一块独立进行加密;解密过程则相反,逐块解密后重组数据。
2. CBC模式(密码分组链接:Cipher-block chaining)
在CBC模式中,每个待加密的明文块在加密前会先与前一个密文块进行异或运算,然后再通过加密器处理。对于第一个明文块,则与一个初始化向量(IV)进行异或运算,以此实现块之间的链接。
3. CFB模式(密文反馈:Cipher feedback)
与ECB和CBC仅处理块数据不同,CFB模式能够将块密文转换为流密文,从而支持对任意长度数据的加密,适用于流式数据传输场景。
4. OFB模式(输出反馈:Output feedback)
OFB模式首先利用块加密器生成密钥流,然后将密钥流与明文流异或得到密文流。解密时,同样生成相同的密钥流,并与密文流异或恢复明文。由于异或操作的对称性,加密与解密流程完全一致。
Python代码实现与解析
二、代码实现与解析
以下展示具体的Python实现代码:
from Crypto.Cipher import AES
import base64
class AEScoder():
def __init__(self):
self.__encryptKey = "iEpSxImA0vpMUAabsjJWug=="
self.__key = base64.b64decode(self.__encryptKey)
# AES加密
def encrypt(self,data):
BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
cipher = AES.new(self.__key, AES.MODE_ECB)
encrData = cipher.encrypt(pad(data))
#encrData = base64.b64encode(encrData)
return encrData
# AES解密
def decrypt(self,encrData):
#encrData = base64.b64decode(encrData)
#unpad = lambda s: s[0:-s[len(s)-1]]
unpad = lambda s: s[0:-s[-1]]
cipher = AES.new(self.__key, AES.MODE_ECB)
decrData = unpad(cipher.decrypt(encrData))
return decrData.decode('utf-8')
简析1:代码采用面向对象设计,创建了一个AEScoder类。为简化示例,密钥被硬编码为类的属性。若需动态修改密钥,可将密钥作为参数传入构造函数或方法中。
简析2:示例默认使用ECB模式,这是AES最简单且常见的模式。若需使用CBC模式,需额外提供初始化向量(iv),例如:cipher = AES.new(self.__key, AES.MODE_CBC, iv)。
简析3:代码中包含pad(填充)和unpad(去填充)函数。由于AES要求加密文本长度必须是密钥字节数的整数倍,此处encryptKey经base64解码后长度为16字节,因此填充逻辑需确保数据长度符合该要求。
简析3拓展:AES标准定义了三种密钥长度,分别对应AES-128、AES-192和AES-256,密钥长度分别为128位(16字节)、192位(24字节)和256位(32字节)。密钥越长,安全性越高,但加解密耗时也相应增加。默认使用的AES-128在大多数场景下已足够安全。
PKCS7填充算法详解
填充算法拓展
文中使用的填充算法名为pkcs7padding。
其原理简单:缺几个字节就填充几个字节的值,每个填充字节的值等于需要填充的字节数。
例如,若需填充8个字节,则每个字节的值为0x08;若需填充7个字节,则每个字节的值为0x07,依此类推。
即使明文长度恰好是Block Size的整数倍,仍需填充一个完整的Block Size长度的数据。这样做的优势在于,解密时只需检查最后一个字节的值,即可准确知道填充了多少字节,从而正确去除填充。
实际上,Java中实现AES加密的默认模式为Cipher.getInstance("AES/ECB/PKCS5Padding")。PKCS#5是PKCS#7的一个子集:PKCS#5仅针对8字节(Block Size=8)进行填充,填充值为0x01至0x08;而PKCS#7支持Block Size范围为1至255字节。由于AES没有64位(8字节)的块,若采用PKCS5,实质上等同于使用PKCS7。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









