AES加密的工作模式ECB、CBC、CFB、OFB及案例

高级加密标准(Advanced Encryption Standard: AES)是美国国家标准与技术研究院(NIST)在2001年建立了电子数据的加密规范。其是对称加解密算法的最经典算法之一,它是一种分组加密标准,每个加密块大小为128位,允许的密钥长度为128、192和256位。这里只介绍ECB、CBC、CFB和OFB四种加密模式

ECB(电子密码本模式)

之所以使用分组密码模式是因为分组密码只能处理定长的数据,如AES处理128bit,那么将明文切分成若干个128bit,分别加密。这种模式就是ECB模式,实际上有很明显的弱点,现在已经不被使用。
在这里插入图片描述
在这里插入图片描述

ECB模式是最简单的一种,它有很严重的问题,就是相同的明文会得到同样的密文。因为每个分组加密方式和密钥都相同,若分组明文相同,加密后密文也相同。

所以需要寻找一种模式,它至少得满足:

  1. 相同的明文分组加密后密文不同。
  2. 明文微小变化都能造成密文有很大变化。

CBC模式(密码分组链接模式)

CBC模式由IBM发明与1976年,在CBC模式中,每个平文块先与前一个密文块进行异或后,再进行加密。在这种方法中,每个密文块都依赖于它前面的所有密文块。同时,为了保证每条消息的唯一性,在第一个块中需要使用初始化向量。

加密跟解密过程如下:
在这里插入图片描述

这里引入了初始化向量IV,因为第一组明文不存在"前一个密文",一般来说每次加密都会生成随机值来做初始 化向量。

CFB模式 (密文反馈模式)

CFB又称密文反馈模式,前一个密文分组会被送入密码算法的输入端,再将输出的结果与明文做异或。与ECB和CBC模式只能够加密块数据不同,CFB能够将块密文(Block Cipher)转换为流密文。

加密跟解密过程如下:
在这里插入图片描述

OFB模式(输出反馈模式)

OFB又称输出反馈模式,前一组密码算法输出会输入到下一组密码算法输入。先用块加密器生成密钥流,然后再将密钥流与明文流异或得到密文流,解密是先用块加密器生成密钥流,再将密钥流与密文流异或得到明文,由于异或操作的对称性所以加密和解密的流程是完全一样的。
在这里插入图片描述
在这里插入图片描述

改变一个明文分组对四种工作模式的影响

  • ECB:只影响当前分组,但相同的明文分组产生相同的密文 ,分组的特点有时是一个严重的安全性弱点
  • CBC:当前分组和后续分组都受影响,可用作认证码
  • OFB:只影响当前分组,可用在卫星通信中
  • CFB:当前分组和后续分组都受影响,可用作认证码

作业案例

输入学号后两位数字 n,出生年份后两位数字 m (00后取99年)。

x1 = n mod 64,
x2 = (n + 20) mod 64,
x3 = (n + 40) mod 64,

初始向量 IV = m mod 64,
K = (1 0 0 1 1 0), Ek(z) = z ⊕ k

求四种模式下的y1, y2, y3?

Python版如下:

# ECB模式
def ecb_enc():
    return x1^key, x2^key, x3^key


# CBC模式
def cbc_enc():
    return (iv^x1)^key, (((iv^x1)^key)^x2)^key, (((((iv^x1)^key)^x2)^key)^x3)^key


# OFB模式
def ofb_enc():
    return x1^(iv^key), x2^((iv^key)^key), x3^(((iv^key)^key)^key)


# CFB模式
def cfb_enc():
    return x1^(iv^key), x2^(x1^(iv^key)^key), x3^(x2^(x1^(iv^key)^key)^key)


# 输入学号后两位数字 n,出生年份后两位数字 m (00后取99年)。
print('请输入学号后两位数字 n:')
n = int(input())
print('请输入出生年份后两位数字 m:')
m = int(input())

x1, x2, x3 =  n % 64, (n + 20) % 64, (n + 40) % 64
iv = m % 64
k = '100110'

key = int(k,2)
print('x1={}, x2={}, x3={}'.format(x1,x2,x3))
# 转为二进制后
print('转为二进制后: x1={}, x2={}, x3={}'.format(bin(x1),bin(x2),bin(x3)))

# ECB模式下
ecb_y1, ecb_y2, ecb_y3 = ecb_enc()
print('ECB模式下: y1={}, y2={}, y3={}, 二进制: y1={}, y2={}, y3={}'.format(ecb_y1, ecb_y2, ecb_y3, bin(ecb_y1), bin(ecb_y2), bin(ecb_y3)))

# CBC模式下
cbc_y1, cbc_y2, cbc_y3 = cbc_enc()
print('CBC模式下: y1={}, y2={}, y3={}, 二进制: y1={}, y2={}, y3={}'.format(cbc_y1, cbc_y2, cbc_y3, bin(cbc_y1), bin(cbc_y2), bin(cbc_y3)))

# OFB模式下
ofb_y1, ofb_y2, ofb_y3 = ofb_enc()
print('OFB模式下: y1={}, y2={}, y3={}, 二进制: y1={}, y2={}, y3={}'.format(ofb_y1, ofb_y2, ofb_y3, bin(ofb_y1), bin(ofb_y2), bin(ofb_y3)))

# CFB模式下
cfb_y1, cfb_y2, cfb_y3 = cfb_enc()
print('CFB模式下: y1={}, y2={}, y3={}, 二进制: y1={}, y2={}, y3={}'.format(cfb_y1, cfb_y2, cfb_y3, bin(cfb_y1), bin(cfb_y2), bin(cfb_y3)))

运行结果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Pioo_/article/details/110878905