分组加密算法

1.实验目的

  • 理解对称加密算法中的5种分组模式。

  • 掌握不同分组模式的特点。

  • 基于C++、Java或.net等环境中成熟的对称加密库实现多种对称加密算法模式。

2.相关理论和实验环境

2.1. 相关基本理论

分组密码(Block Cipher)是一种对称加密算法,它将明文分成固定长度的块(通常为64或128比特)进行加密和解密。分组密码的基本原理在于通过特定的算法将这些固定长度的块进行处理,以确保数据的机密性和完整性。分组密码算法的使用方式主要包括电码本工作模式、密文分组链接工作模式,密文反馈工作模式,输出反馈工作模式,计数器工作模式,分组连接模式等 [1]  以下是几种常见的分组模式:

1. 电子密码本模式(Electronic Codebook Mode, ECB)

原理:将明文分成固定长度的块,每个块独立加密。相同的明文块总是会被加密为相同的密文块。

优点:简单易实现,适用于短数据量加密。每个明文小组的加密不依赖其他组,可以并行处理[3]

缺点:相同的明文块会产生相同的密文块,容易被模式识别和分析,安全性较低。

原理图

ECB

2. 密文分组链接模式(Cipher Block Chaining Mode, CBC)

原理:在加密每个明文块之前,将其与前一个密文块进行异或(XOR)操作。第一个明文块则与一个初始化向量(IV)进行异或操作。

优点:每个明文块的加密结果都与前一个密文块有关,提高了安全性。相同的明文块在不同的上下文中会产生不同的密文块,隐藏了明文的数据模式,使攻击者很难进行统计、猜测攻击[3]

缺点:需要IV,且加密过程必须按顺序进行,不适合并行处理。

原理图

CBC

3. 密文反馈模式(Cipher Feedback Mode, CFB)

原理:将一个密钥流与明文块进行异或操作生成密文块。密钥流是通过将前一个密文块加密后得到的。

优点:适合处理流数据,可以生成任意长度的密文块。

缺点:加密过程需要串行进行,不适合并行处理。

原理图

CFB

4. 输出反馈模式(Output Feedback Mode, OFB)

原理:与CFB类似,但密钥流是通过不断加密一个初始化向量(IV)生成的,与明文无关。

优点:可以生成预先计算好的密钥流,适合并行处理,能避免错误传播。

缺点:可能对明文进行主动攻击;存在输出反 馈,难以进行并行运算;需要共同的移位寄存器初始 值IV,对于不同的消息,IV必须唯一;通信双方必须 同步,否则难以解密,不过可以采用带有同步时钟的编码进行解决[2]

原理图

OFB

5. 计数器模式(Counter Mode, CTR)

原理:使用一个计数器值与密钥进行加密生成密钥流,然后与明文块进行异或操作。

优点:每个块的加密可以并行处理,适合高性能需求。只需保证计数器不重复,即可保证安全性。

缺点:需要维护一个唯一的计数器值。

原理图

CTR

分组模式对比表格

分组模式 原理 优点 缺点
ECB 独立加密每个块 简单易实现,支持并行计算 易被模式识别,安全性低
CBC 每个块与前一个密文块异或 安全性高,能够解密任意密文分组 需要IV,不适合并行处理,加密不支持并行计算
CFB 利用前一个密文块生成密钥流 适合流数据处理,不需要填充,能够解密任意密文分组 不适合并行处理
OFB 生成独立密钥流 适合并行处理,不需要填充,加密解密使用相同的结构 需要IV,密钥流重复使用降低安全性,不支持并行计算
CTR 利用计数器生成密钥流 适合高性能需求,不需要填充,加密解密使用相同的结构 需要维护唯一计数器,主动攻击者反转密文分组中的某些比特时明文分组中相对应的比特也会被反转。

2.2 实验环境构建

1) 选择语言及原因

选择Java作为开发语言,原因如下 :

  • Java广泛用于企业级应用,具有良好的跨平台性。
  • 丰富的加密库和社区支持,如javax.crypto包和第三方库BouncyCastle。
  • 已经安装配置过Java环境。

image-20240601215705595

2) 选择加密算法库

选择Java内置的javax.crypto库,包含常见的对称加密算法如AES。此库可以设置不同的分组模式。

函数原型及参数设置

  • 加密:Cipher.getInstance("AES/模式/填充")
  • 分组模式参数示例:
    • ECB模式:Cipher.getInstance("AES/ECB/PKCS5Padding")
    • CBC模式:Cipher.getInstance("AES/CBC/PKCS5Padding")
    • CFB模式:Cipher.getInstance("AES/CFB/PKCS5Padding")
    • OFB模式:Cipher.getInstance("AES/OFB/PKCS5Padding")
    • CTR模式:Cipher.getInstance("AES/CTR/NoPadding")

3.实验内容和结果分析

3.1 程序的设计和探索

1) 实现加密/解密程序

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package password_test1;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;

public class EncryptDecrypt {

public static void main(String[] args) throws Exception {
try {
// 加载密钥
SecretKey key = loadKey("password.txt");

// 处理两个明文文件
for (int i = 1; i <= 2; i++) {
// 读取明文文件
String plaintext = readFile("plaintext" + i + ".txt");

// 混合模式加密
String mixedCiphertext = encryptMixed(plaintext, key);
// 将密文写入文件
String mixedCiphertextFile = "ciphertext-mixed" + i + ".txt";
writeFile(mixedCiphertextFile, mixedCiphertext);
System.out.println("Written mixed ciphertext to: " + mixedCiphertextFile);

// 混合模式解密
String mixedDecryptedText = decryptMixed(mixedCiphertext, key);
// 将解密后的明文写入文件
String mixedResultFile = "result-mixed" + i + ".txt";
writeFile(mixedResultFile, mixedDecryptedText);
System.out.println("Written mixed decrypted text to: " + mixedResultFile);
}
} catch (Exception e) {
e.printStackTrace();
}
}

// 从文件中读取密码并生成AES密钥
public static SecretKey loadKey(String passwordFile) throws Exception {
String password = readFile(passwordFile);
byte[] key = hashKey(password);
SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
return secretKey;
}

// 使用SHA-256哈希算法生成256位的密钥
public static byte[] hashKey(String key) throws Exception {
MessageDigest sha = MessageDigest.getInstance("SHA-256");
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
return sha.digest(keyBytes);
}

// 读取指定文件的内容
public static String readFile(String fileName) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
return sb.toString();
}

// 将内容写入指定文件
public static void writeFile(String fileName, String data) throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
writer.write(data);
writer.close();
}

// 使用指定模式对明文进行加密
public static String encrypt(String plainText, SecretKey key, String mode) throws Exception {
Cipher cipher = getCipherInstance(mode, Cipher.ENCRYPT_MODE, key);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
}

// 使用指定模式对密文进行解密
public static String decrypt(String cipherText, SecretKey key, String mode) throws Exception {
Cipher cipher = getCipherInstance(mode, Cipher.DECRYPT_MODE, key);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(cipherText));
return new String(decryptedBytes);
}

// 根据模式获取Cipher实例并进行初始化
public static Cipher getCipherInstance(String mode, int cipherMode, SecretKey key) throws Exception {
String transformation;
if (mode.equals("CTR")) {
transformation = "AES/CTR/NoPadding";
} else {
transformation = "AES/" + mode + "/PKCS5Padding";
}
Cipher cipher = Cipher.getInstance(transformation);
if (!mode.equals("ECB")) {
// 非ECB模式需要初始化向量IV
IvParameterSpec ivSpec = new IvParameterSpec(new byte[16]);
cipher.init(cipherMode, key, ivSpec);
} else {
cipher.init(cipherMode, key);
}
return cipher;
}

// 使用混合模式对明文进行加密
public static String encryptMixed(String plainText, SecretKey key) throws Exception {
int halfLength = plainText.length() / 2;
String firstHalf = plainText.substring(0, halfLength);
String secondHalf = plainText.substring(halfLength);

// 使用ECB模式加密第一部分
String encryptedFirstHalf = encrypt(firstHalf, key, "ECB");
// 使用CBC模式加密第二部分
String encryptedSecondHalf = encrypt(secondHalf, key, "CBC");

return encryptedFirstHalf + encryptedSecondHalf;
}

// 使用混合模式对密文进行解密
public static String decryptMixed(String cipherText, SecretKey key) throws Exception {
int halfLength = cipherText.length() / 2;
String encryptedFirstHalf = cipherText.substring(0, halfLength);
String encryptedSecondHalf = cipherText.substring(halfLength);

// 使用ECB模式解密第一部分
String decryptedFirstHalf = decrypt(encryptedFirstHalf, key, "ECB");
// 使用CBC模式解密第二部分
String decryptedSecondHalf = decrypt(encryptedSecondHalf, key, "CBC");

return decryptedFirstHalf + decryptedSecondHalf;
}
}

代码注释说明

  • 加载密钥:从password.txt读取密码,并生成AES密钥。
  • 读取文件:从指定文件中读取明文或密文。
  • 写入文件:将加密后的密文或解密后的明文写入文件。
  • 加密方法:使用指定模式对明文进行加密。
  • 解密方法:使用指定模式对密文进行解密。
  • 获取Cipher实例:根据模式创建Cipher实例,并进行初始化。

3. 实验内容和结果分析

3.1. 程序的设计和实现框架

正文内容: 本实验的目的是实现对称加密算法(AES)在五种不同分组模式下的加密和解密操作。程序采用Java语言编写,并使用内置的javax.crypto库来实现加密算法。程序包括读取明文和密码、加密、存储密文、解密、以及输出结果的功能。

设计框架如下:

  1. 加载并解析密码文件,生成AES密钥。
  2. 读取明文文件,进行分组加密操作。
  3. 将加密后的密文保存到对应文件。
  4. 读取密文文件,进行分组解密操作。
  5. 将解密后的明文输出到控制台和结果文件。

程序结构:

  • EncryptDecrypt类:包含主方法和加解密操作的方法。
  • loadKey方法:从文件中读取密码并生成密钥。
  • readFile方法:读取指定文件的内容。
  • writeFile方法:将内容写入指定文件。
  • encryptdecrypt方法:实现加密和解密操作。
  • getCipherInstance方法:根据分组模式初始化Cipher实例。

3.2. 基本的分组加解密实验

1) 实验过程说明

在本实验中,分别使用ECB、CBC、CFB、OFB、CTR五种分组模式对明文文件进行加密和解密。具体步骤如下:

  1. plaintext1.txtplaintext2.txt读取明文内容。
  2. password.txt读取加密密码并生成AES密钥。
  3. 使用五种分组模式对明文进行加密,将密文分别存储在ciphertext-ecb.txtciphertext-cbc.txtciphertext-cfb.txtciphertext-ofb.txtciphertext-ctr.txt文件中。
  4. 从上述密文文件中读取密文内容,使用相同的密码进行解密,将解密后的明文输出到result-ecb.txtresult-cbc.txtresult-cfb.txtresult-ofb.txtresult-ctr.txt文件中。

2) 结果展示及分析

image-20240601143536579

实验结果如下:

  • 原始明文与解密后的明文一致,验证了加密和解密操作的正确性。
  • 不同分组模式的加密密文不同,验证了各分组模式的独特性。

具体结果展示如下:

plaintext1.txt

1
2
Another line of text for testing.
This is the second plaintext file used in the encryption and decryption test.

ECB模式:

  • 密文

    1
    G0QfajFVT+RFCa4S8UC67WjKpbWTLlorveZTnr1TQYEzfCsX9yUwwKubl4fxry/KiRVtVUSYmSj+NuyuQ7mkW1nCLGoKTQCdUmypt+I4iML3hsfEkI7dvBgTgM3s5670
  • 明文:

1
Hello, this is a test message.This message is used for encryption and decryption testing.

CBC模式:

  • 密文
1
G0QfajFVT+RFCa4S8UC67W1mFf0BtqJYhNeO/EntI9D/bN4cAVI/nVqqaESieE7eA/f4vUalFVPI0VVNhUQCYpgMq6y+xaMCHtabELKJ4EFrWAbelxC29f7adJNhIF0J
  • 明文
1
Hello, this is a test message.This message is used for encryption and decryption testing.

CFB模式:

  • 密文
1
0pztM7tv+YFL6Rm2eBSAXkgRIQmW3Jcb/Die5huy+lvuJ/cy1x2IkRxt+vOBVL7dO5GFTKo0GK/nBzTPwngp0ueEssriTWEUo2K9P5l/pjKv8PBohiLkZYH4D/ftozq9
  • 明文
    1
    Hello, this is a test message.This message is used for encryption and decryption testing.

OFB模式:

1
0pztM7tv+YFL6Rm2eBSAXi5Jl6PtgJ820fZzhBIxd01W2R7HuuEyTG1QfEdWrFxTjyFFQfcWIPbKAPb11t9UQ1TW6Sez92L5nshaQcRR2Tw/6muF1K7uRIA8xoWG8kv+
  • 明文
    1
    Hello, this is a test message.This message is used for encryption and decryption testing.

CTR模式:

1
0pztM7tv+YFL6Rm2eBSAXvvDDsxXjfny1R4ryiml7riLlUOFDx2DsNpzfOSVlA/+UsfcYxH7jVwrgXLYRFSGROUzWFiPecJspjYqZWK6rlNAqTTJf2pzcIs=
  • 明文
    1
    Hello, this is a test message.This message is used for encryption and decryption testing.

plaintext2.txt

image-20240601203927068

ECB模式:

  • 密文

    1
    t/Hqwwagwy9ReH/ZlvosEPca7jvFGHWlvmeYeXqqgxSiTicxxX6QWkyliA50zQnesZnLHf6/aVze8gSrNCmyT7JPbEO5MFWwvenK0LD2rHnoq35qn3WW56/7tz0vvqJqaCOZT5uJBIJL2GSZlcQKEw==
  • 明文:

1
Another line of text for testing.This is the second plaintext file used in the encryption and decryption test.

CBC模式:

  • 密文
1
t/Hqwwagwy9ReH/ZlvosEDBT37cc0qETXpztVEh7qloLMqKF1iDTH0hd5iYROtzJ51glcPA6VkMJHKP1fitj79GKBsANGf7NhDqDG/cXKZasg8JEYHcgxPMkuepf8iyS1evKpaxgpau4BbjRCIiopg==
  • 明文
1
Another line of text for testing.This is the second plaintext file used in the encryption and decryption test.

CFB模式:

  • 密文
1
0pztM7tv+YFL6Rm2eBSAXkgRIQmW3Jcb/Die5huy+lvuJ/cy1x2IkRxt+vOBVL7dO5GFTKo0GK/nBzTPwngp0ueEssriTWEUo2K9P5l/pjKv8PBohiLkZYH4D/ftozq9
  • 明文
    1
    25fuK7wmq9VP6QTzMQjGH5YzBdWjQGJJ2lC/4nxEq4cXQbZY0vXFXQdyFd1+jWHBGPmHDplI6x0Yk3QnWZbwR2hvC5gBBZ/OALDUjunwmqq0q1rFk2JEKWkjZ4cqxlTTcW3F8DFcG0rp8Ko4cJ81Aw==

OFB模式:

  • 密文
1
25fuK7wmq9VP6QTzMQjGH3pYiqS5xp0hgvF3kAN2TUIR/lbDrLIoXipBNEsF/0xDhSsBB+gIYfrKF+H00otbRVaTqDyksmK8lNQDRdhdljdx/XyP0LPpTMAboOzl1SicZL8NvlZZt/oIU0lOs1t+dQ==
  • 明文
    1
    Another line of text for testing.This is the second plaintext file used in the encryption and decryption test.

CTR模式:

  • 密文
1
25fuK7wmq9VP6QTzMQjGH6/SE8sDy/vlhhkv3jji1LfMsguBGU6Zop1iNOjGxx/uWM2YJQ7lzFArlmXZQACJQud2GUOYPMIprCpzYX624VgOviPDe3d0eMvu6HvtGDS8ETTn1nBTJhJ+H15EcC4=
  • 明文
    1
    Another line of text for testing.This is the second plaintext file used in the encryption and decryption test.

通过实验验证了不同分组模式在加密和解密操作中的独特表现,同时保证了明文在加密和解密后的完整性。

3.3. 分组模式的混用实验

1) 实验过程说明

在本实验中,尝试将不同的分组模式混合使用。例如,使用ECB模式加密前一半明文,使用CBC模式加密后一半明文。实验步骤如下:

  1. plaintext1.txtplaintext2.txt读取明文内容。
  2. 将明文分成两部分,前一半使用ECB模式加密,后一半使用CBC模式加密。
  3. 将加密后的密文分别存储在ciphertext-mixed.txt文件中。
  4. 从密文文件中读取密文内容,分别使用ECB和CBC模式进行解密,将解密后的明文输出到result-mixed.txt文件中。

2) 结果展示及分析

实验结果如下:

  • 原始明文与解密后的明文一致,验证了分组模式混合使用的可行性。
  • 混合模式下的密文仍然具备较高的安全性,不同分组模式的组合增加了破解难度。

具体结果展示如下:

​ plaintest1

  • 密文:

    1
    G0QfajFVT+RFCa4S8UC67WjKpbWTLlorveZTnr1TQYFtmEGJqvJOV4KxJCyYuktGedwxwrVZniGHGa1507W51ZK+I8TTXUSStM6RsL3Ame8GaozBWehEjDcw7ipyu1Qv
  • 明文:

    1
    Hello, this is a test message.This message is used for encryption and decryption testing.

    plaintext2:

  • 密文:

    1
    t/Hqwwagwy9ReH/ZlvosEPca7jvFGHWlvmeYeXqqgxSiTicxxX6QWkyliA50zQne/Mgd96IdpLKtOYPIuhojdQ==nvTGG17OlCb4XSlNFlYJW1t0JoDH14cf98/aloTq0/Sl0AIgTN5YXRFEB4EmXwVxxfDE4WxhA0z02/GPY0G+dw==
  • 明文:

    1
    Another line of text for testing.This is the second plaintext file used in the encryption and decryption test.

通过实验验证了分组模式的混用可以在保证安全性的同时增加灵活性,并且保证了明文在加密和解密后的完整性。

3.4. 明文-密文-分组模式的关联关系实验

1) 实验过程说明

在本实验中,研究不同分组模式下明文和密文之间的关联关系。实验步骤如下:

  1. plaintext1.txtplaintext2.txt读取明文内容。
  2. 分别使用五种分组模式对明文进行加密,将密文存储在相应的文件中。
  3. 对比不同分组模式下密文的异同,分析分组模式对密文模式的影响。

2) 结果展示及分析

实验结果如下:

  • 不同分组模式下的密文差异明显,验证了分组模式对密文模式的影响。
  • ECB模式下相同的明文块产生相同的密文块,其他模式则不会。

4.总结与展望

分组密码是对称密码体制中的一种应用方式,由于不同应用环境对解密过程的需求诞生了不同的工作模式。随着信息技术的发展,分组密码也在不断地完善和升级,从而实现更高的效率,更强的灵活性和安全性。

参考文献

[1] 分组密码算法的工作模式.张立廷. 信息安全技术,2021(1)

[2] 一种分组密码的工作模式.黄文庆.中国高新技术企业,2011(1)

[3] 分组密码工作模式的分析及应用.刘平.南阳理工学院学报,2013(2)