文章目录
- 简述
- python中常用于AES加密解密的库
- AES常用加密模式及填充方式
- 使用pycrypto加密解密实例
- 使用pycryptodome加密解密实例
简述
AES(Advanced Encryption Standard)是一种对称加密算法,常用于保护敏感数据的机密性。它采用了替代算法(substitution)和置换算法(permutation)的组合,使用相同的密钥对数据进行加密和解密。
python中常用于AES加密解密的库
在Python中,有几个常用的库可用于进行AES加密和解密。以下是其中一些常见的库:
cryptography:这是一个功能强大且易于使用的加密库,支持多种对称和非对称加密算法,包括AES。它提供了高级的加密原语和密码学操作,适用于各种加密需求。
pycryptodome:这是一个功能齐全的密码学库,是PyCrypto库的一个分支,提供了对称和非对称加密算法的实现,包括AES。它具有广泛的功能,并且在实现中经过了广泛的测试和使用。
cryptography.io:这是一个基于cryptography库的高级加密工具包,提供了易于使用的高级加密功能。它支持多种加密模式和填充方案,并提供了更高级别的API,简化了加密和解密操作。
pycrypto:这是一个古老的密码学库,提供了对称和非对称加密算法的实现,包括AES。尽管该库不再维护,但在一些旧的项目中仍然被广泛使用。
AES常用加密模式及填充方式
在AES中,常用的加密模式(mode)和填充(padding)方式如下:
加密模式(Mode of Operation):
- ECB(Electronic Codebook):最简单的模式,将每个分组独立加密,没有使用IV(Initialization Vector)。
- CBC(Cipher Block Chaining):使用前一个分组的密文与当前分组的明文进行异或操作,引入了IV以增加随机性。
- CFB(Cipher Feedback):将前一个密文块作为密钥加密当前明文块,再将得到的密文与明文进行异或操作。
- OFB(Output Feedback):类似于CFB模式,但使用的是一个可变的非密钥变量,称为反馈变量(feedback variable)。
- CTR(Counter):使用一个计数器和密钥生成密钥流,然后将密钥流与明文进行异或操作得到密文。
填充方式(Padding):
- PKCS#7(或PKCS#5):使用合适的字节填充明文,填充字节的值为缺少的字节数。
- Zero Padding:在明文末尾添加零字节,直到满足块大小的要求。
- ANSI X.923:在明文末尾添加零字节,并在最后一个字节处写入填充长度。
- ISO 10126:在明文末尾添加随机生成的字节,并在最后一个字节处写入填充长度。
选择加密模式和填充方式需要根据具体的安全需求和应用场景来决定。需要注意的是,ECB模式由于没有引入IV和每个分组独立加密的特性,会带来一些安全性问题,因此在实际应用中,推荐使用更安全的模式(如CBC、CTR等)并配合适当的填充方式。
使用pycrypto加密解密实例
from Crypto.Cipher import AES def encrypt(key, mode, text): # 创建一个AES加密器/解密器对象 cryptor = AES.new(key.encode('utf-8'), mode, key.encode('utf-8')) block_size = AES.block_size # 进行零字节填充 padding_length = block_size - (len(text) % block_size) padded_text = text + b'\0' * padding_length # ---------------------------------------- # 除了零字节填充也可以使用PKCS#7填充 # padding_length = block_size - (len(text) % block_size) # padded_text = text + padding_length.to_bytes(1, 'big') * padding_length # 加密 ciphertext = cryptor.encrypt(text) # 对解密后数据解码为字符串,两种方式 # 十六进制表示 # 适用于需要可读性较高的表示或者在网络中以文本形式传输二进制数据。 import binascii hex_text = binascii.b2a_hex(ciphertext).decode('utf-8') # Base64 编码 # 适用于文本传输和存储 import base64 encoded_text = base64.encodebytes(ciphertext).decode('utf-8').strip() def decrypt(key, mode, text): # 解密 cryptor = AES.new(key.encode('utf-8'), mode, key.encode('utf-8')) # 文本十六进制转二进制解密 plain_text = cryptor.decrypt(a2b_hex(text)).decode("utf8") # 在解密后需要对加密内容进行去填充操作 plain_text = plain_text.rstrip(bytes('\0', 'utf-8')) # 文本base64解码 res = base64.decodebytes(decrData.encode("utf8")) plain_text = cryptor.decrypt(res).decode("utf8") # 在解密后需要对加密内容进行去填充操作 plain_text = unpad_pkcs7(plain_text) # pkcs7去填充操作 def unpad_pkcs7(data): padding_len = data[-1] return data[:-padding_len]
使用pycryptodome加密解密实例
import base64 from Crypto.Cipher import AES from Crypto.Util.Padding import pad def encrypt(key, mode, text): # 使用key,选择加密方式 cryptor = AES.new(key.encode('utf-8'), AES.MODE_CBC, key.encode('utf-8')) # 使用pkcs7补全 pad_pkcs7 = pad(text.encode('utf-8'), AES.block_size, style='pkcs7') ciphertext = cryptor.encrypt(pad_pkcs7) # 加密结果 ciphertext = base64.encodebytes(ciphertext).decode('utf-8').strip() def decrypt(key, mode, text): cryptor = AES.new(key.encode('utf-8'), AES.MODE_CBC, key.encode('utf-8')) # 对传入的text转换为字节码 text = base64.decodebytes(text.encode("utf8")) # 对解密结果转换为字符串 plain_text = cryptor.decrypt(text).decode("utf8") # 对PKCS7进行去填充操作 plain_text = unpad_pkcs7(plain_text) # pkcs7去填充操作 def unpad_pkcs7(data): padding_len = data[-1] return data[:-padding_len]