AES加密
- 明文P:
未经加密的数据
- 密钥K:
用来加密明文的密码,在对称加密算法中,加密与解密的密钥是相同的
密钥为接收方与发送方协商产生,但不可以直接在网络上传输,否则会导致密钥泄漏,通常是通过非对称加密算法加密密钥,然后再通过网络传输给对方,或者直接面对面商量密钥。密钥是绝对不可以泄漏的,否则会被攻击者还原密文,窃取机密数据
- AES加密函数:
将明文转化为密文的函数,例如:AES加密函数为E,则 C = E(K, P),其中P为明文,K为密钥,C为密文 - 密文C:
经加密函数处理后的数据 - AES解密函数:
将密文转化为明文的函数,例如:
AES解密函数为D,则 P = D(K, C),其中C为密文,K为密钥,P为明文
加密过程:
加密过程:
明文的处理:
- 分块:AES采用分块加密的方式,将明文划分为若干个等长的,明文块,每个块的大小为128位(16字节),若明文长度不为128的整数倍,则必须进行填充(
当前明文长度为n(以字节为单位),那么需要补充的字节长度k为 k=n*(16-n mod 16)
)
- 转换:将处理后的明文转化为一个4x4字节的矩阵,每个字节分别填入不同的位置
例如:
密钥:
密钥的长度可以是128位、192位、256位,在后面的循环运算中分别需要进行10轮、12轮、14位。以128位密钥为例,最终将密钥转化为4x4矩阵
加密流程(以128位密钥为例):
- 轮密钥加:将当前状态数组与当前轮的轮密钥进行异或(XOR)操作
- 字节代换:使用一个固定的S-Box(替换字典),对状态数组中的每个字节进行替换
- 行位移:对状态数组的每一行进行循环左移。第一行不变,第二行左移1个字节,第三行左移2个字节,第四行左移3个字节
- 列混合:对状态数组的每一列进行线性变换
解密过程:
不同模式
- 电子密码本模式(ECB,Electronic Codebook)
特点:
- 每个块独立加密:ECB 模式将数据分成固定大小的块,然后独立加密每个块
- 不使用 IV:在 ECB 模式中,没有初始化向量(IV)的概念。
- 简单:实现简单,但安全性较差
- 密码分组链接模式(CBC,Cipher Block Chaining)
特点:
- 链式加密:每个明文块在加密前会与前一个密文块进行异或操作,然后再加密。这种方式使用了初始化向量(IV)
- 使用 IV:IV 在加密过程中是必要的,并且必须在解密时保持一致
- 密码反馈模式(CFB,Cipher Feedback)
特点:
- 流式加密:将块加密器转换为流加密器,使用加密块的前部分生成密钥流,并与明文进行异或操作
- IV 使用:IV 必须在加密时保持一致
相关代码实现
需先安装pycryptodome库
pip intsall pycryptodome
导包
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
设置key和iv
#生成密钥
key = b'1234567812345678'
#设置偏移量
iv = b'1234567812345678'
注意:key的长度需要是16字节的倍数 iv的长度必须是16字节
生成加密器
aes1 = AES.new(key=key,iv=iv,mode=AES.MODE_CBC)
#参数key和iv的类型需要是字节
加密
text = '装逼我让你飞起来'
en_text = aes1.encrypt(text.encode('gbk'))
#参数类型是字节,且字节长度需要是16的倍数
print(en_text)
生成解密器将刚才的密文解密
aes2 = AES.new(key=key,iv=iv,mode=AES.MODE_CBC)
den_text = aes2.decrypt(en_text)
print(den_text.decode("gbk"))
注意:不能用加密的对象再去解密,所以又创建一个解密对象
上述情况的数据通过encode(“GBK”)编码后刚好是16字节,那如果不是16的倍数应该怎么办
那么就需要用到pad模块中的方法将数据补齐
例如:
字节长度位26
使用pad( )方法补齐
text = "让你见识见识什么叫噩梦缠绕" #26字节
pad_text = pad(text.encode('gbk'),AES.block_size)
加密
en_text = aes1.encrypt(pad_text)
print(en_text)
解密
den_text = aes.decrypt(en_text)
print(den_text.decode("gbk"))