图解密码技术-CFB模式

分组密码(Block Cipher)是一种密码对称加密算法,特点是按照固定长度的块(block)来对数据进行加密和解密。

常见的分组密码以及特点

常见的分组密码有DES、AES、SM4、Blowfish等。

分组密码的特点

  1. 分组长度固定,常见的块长度有64位、128位、256位等
  2. 可以将数据进行分组,切割为不同的数据块,每一块数据单独处理加密
  3. 使用对称密钥,加解密使用的是同一个密钥
  4. 加解密算法是确定的,相同的明文、密钥和加密算法会产生相同的密文

分组密码的工作模式

分组密码算法只能加密固定长度的分组,但是我们需要加密的明文可能会超过分组密码分组的长度,这时候就需要对明文进行切割,分成几组分别进行加密,直到所有的明文加密完成。这种方式就称之为分组密码的模式

分组密码的主要模式

  1. ECB模式:(Electronic CodeBook mode) 电子密码本模式
  2. CBC模式:(Cipher Block Chaining mode) 密码分组链接模式
  3. CFB模式:(Cipher FeedBack mode) 密文反馈模式
  4. OFB模式:(Output FeedBack mode)输出反馈模式
  5. CTR模式:(CounTeR mode) 计数器模式

今天来了解一下CFB模式。

CFB模式

CFB模式的全称是 Cipher FeedBack mode(密文反馈模式)。在CFB中模式中,前一个密文分组会被送回到密码算法的输入端。简单理解就是,前一个密文分组在此加密后会当作下一次与明文异或运算的一部分,依次类推。加密过程如下图:

image-20230810223911494

在CBC模式中,前一个密文分组要和明文组先进行异或运算然后加密最后产生密文分组。如同:

image-20230810224528410

在CFB模式中,前一个密文分组先进行了加密然后使用加密后的数据和下一个明文分组进行异或运算最后产生密文分组。

image-20230810224543646

在CFB模式中,密码算法的输出值会当作下一次与明文加密的“初始化向量”。书中使用了更加专业的术语——“密钥流”。密码算法就相当于一个伪随机数的生成器,而真正的初始化向量则为一个源头。明文数据可以被一个比特一个比特的加密,因此我们可以将CFB模式看做是使用了分组密码来实现流密码的一种方式。

流密码

简单解释就是,加密的密钥流比喻为一个旋转门,我们需要加密的明文就像是一群人。这个旋转门每次只能过去一个人,当所有人一个个的通过旋转门的时候就会与当前旋转门进行一次异或运算。旋转门每一次转动都会产生一个不同的数字,这样当人通过的时候异或的结果也不一样。最终当所有人通过那么就会得到最后的加密之后的数据。

Java代码实现CFB加解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static void main(String[] args) throws Exception {
// 创建一个AES密钥
SecretKeySpec key = new SecretKeySpec("1234567890123456".getBytes(StandardCharsets.UTF_8), "AES");

// 创建一个初始化向量
IvParameterSpec iv = new IvParameterSpec("1234567890123456".getBytes(StandardCharsets.UTF_8));

// 创建一个AES/CFB/PKCS5Padding模式的Cipher
Cipher cipher = Cipher.getInstance("AES/CFB/PKCS5Padding");

// 初始化Cipher为加密模式,设置密钥和初始化向量
cipher.init(Cipher.ENCRYPT_MODE, key, iv);

// 对"Hello World"字符串进行加密
byte[] encrypted = cipher.doFinal("Hello World".getBytes(StandardCharsets.UTF_8));

// 将加密后的数据进行Base64编码,方便打印
String encryptedBase64 = Base64.getEncoder().encodeToString(encrypted);
System.out.println("Encrypted: " + encryptedBase64);

// 初始化Cipher为解密模式,设置密钥和初始化向量
cipher.init(Cipher.DECRYPT_MODE, key, iv);

// 对加密后的数据进行解密
byte[] decrypted = cipher.doFinal(Base64.getDecoder().decode(encryptedBase64));

// 打印解密后的字符串
System.out.println("Decrypted: " + new String(decrypted, StandardCharsets.UTF_8));
}

CFB模式的攻击方式

书中攻击方式我没有看懂….后期补上