1. 前言
AES是一种对称加密,所谓对称加密就是加密与解密使用的秘钥是一个。
之前写过一片关于python AES加密解密的文章,但是这里面细节实在很多,这次我从 参数类型、加密模式、编码模式、补全模式、等等方面 系统的说明如何使用AES加密解密。
看文章不能急功近利,为了解决一个问题临时查到一个代码套用进去,或许可以迅速解决问题,但是遇到新的问题还需要再次查询,这种我认为还是比较浪费时间的。我相信看完认真看完这篇文章的你会大有收获。
2. 环境安装
pip uninstall crypto
pip uninstall pycryptodome
pip install pycryptodome
前面两个卸载命令是为了防止一些安装环境问题,具体请看文章
3.加密模式
AES 加密最常用的模式就是 ECB模式 和 CBC 模式,当然还有很多其它模式,他们都属于AES加密。ECB模式和CBC 模式俩者区别就是 ECB 不需要 iv偏移量,而CBC需要。
4.AES加密使用参数
以下参数都是在python中使用的。
参数
作用及数据类型
秘钥
加密的时候用秘钥,解密的时候需要同样的秘钥才能解出来; 数据类型为bytes
明文
需要加密的参数; 数据类型为bytes
模式
aes 加密常用的有 ECB 和 CBC 模式(我只用了这两个模式,还有其他模式);数据类型为aes类内部的枚举量
iv 偏移量
这个参数在 ECB 模式下不需要,在 CBC 模式下需要;数据类型为bytes
下面简单的一个例子ECB模式加密解密 :
from Crypto.Cipher import AES
password = b'1234567812345678' #秘钥,b就是表示为bytes类型
text = b'abcdefghijklmnhi' #需要加密的内容,bytes类型
aes = AES.new(password,AES.MODE_ECB) #创建一个aes对象
# AES.MODE_ECB 表示模式是ECB模式
en_text = aes.encrypt(text) #加密明文
print("密文:",en_text) #加密明文,bytes类型
den_text = aes.decrypt(en_text) # 解密密文
print("明文:",den_text)
输出:
密文: b'WUà£??\]O×?? )'
明文: b'abcdefghijklmnhi'
以上是针对ECB模式的加密解密,从这个例子中可以看出参数中有几个限制。
- 秘钥必须为16字节或者16字节的倍数的字节型数据。
- 明文必须为16字节或者16字节的倍数的字节型数据,如果不够16字节需要进行补全,关于补全规则,后面会在补全模式中具体介绍。
通过CBC模式例子:
from Crypto.Cipher import AES
password = b'1234567812345678' #秘钥,b就是表示为bytes类型
iv = b'1234567812345678' # iv偏移量,bytes类型
text = b'abcdefghijklmnhi' #需要加密的内容,bytes类型
aes = AES.new(password,AES.MODE_CBC,iv) #创建一个aes对象
# AES.MODE_CBC 表示模式是CBC模式
en_text = aes.encrypt(text)
print("密文:",en_text) #加密明文,bytes类型
aes = AES.new(password,AES.MODE_CBC,iv) #CBC模式下解密需要重新创建一个aes对象
den_text = aes.decrypt(en_text)
print("明文:",den_text)
输出:
密文: b'??N!?~>°Mo??74;0'
明文: b'abcdefghijklmnhi'
通过上面CBC模式的例子,可以简单看出CBC模式与ECB模式的区别:AES.new() 解密和加密重新生成了aes对象,加密和解密不能调用同一个aes对象,否则会报错TypeError: decrypt() cannot be called after encrypt()
。
总结:
1. 在Python中进行AES加密解密时,所传入的密文、明文、秘钥、iv偏移量、都需要是bytes(字节型)数据。python 在构建aes对象时也只能接受bytes类型数据。
2.当秘钥,iv偏移量,待加密的明文,字节长度不够16字节或者16字节倍数的时候需要进行补全。
3. CBC模式需要重新生成AES对象,为了防止这类错误,我写代码无论是什么模式都重新生成AES对象。