应用密码学第一次作业(9.23)
一、Please briefly describe the objectives of information and network security,such as confidentiality, integrity, availability , authenticity , and accountability
The objectives of information and network security include:
- Confidentiality: Protecting sensitive information from unauthorized access.
- Integrity: Ensuring data accuracy and preventing unauthorized modifications.
- Availability: Ensuring resources are accessible to authorized users when needed.
- Authenticity: Verifying the identities of users and systems to confirm that communications are genuine.
- Accountability: Ensuring that user and system actions can be tracked and recorded for auditing and compliance.
二、Please encrypt the message “ Must see you at the fifth teaching building”, by using Playfair cipher with the keyword “GUETT”
Fill the keyword matrix with the rest of letters ,and remove duplicate letters
Group plain text
Mu st se ey ou at th ef if th te ac hi ng bu il di ng
KT RA QA TX PG GA AF TD MB AF AT UH BN IA CG KM BL IA
Code examples are given below:
1.#include<iostream>
2.#include<cstring>
3.
4.using namespace std;
5.void encrypt()
6.{
7. const int N = 100;
8. char letters[26] = "ABCDEFGHIKLMNOPQRSTUVWXYZ";//用于填充矩阵
9. int flag[25] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };//字母是否已在矩阵中,与letters数组对应
10. char ch[5][5];//5X5矩阵
11. char ch1[N];//密钥
12. char ch2[N];//明文
13. char ch4;//无关字符
14. int len = 'a' - 'A';
15. cout << "输入密钥:";
16. cin >> ch1;
17. int flg = 1;
18. while (flg == 1)
19. {
20. for (int i = 0; i < strlen(ch1); i++)//把所输入的密钥转化为大写字母
21. {
22. if (ch1[i] > 'z' || ch1[i] < 'a')
23. {
24. cout << "请重新选择操作:" << endl;
25. flg = 0; break;
26. }
27. else
28. ch1[i] = ch1[i] - len;
29. }
30. if (flg == 1)
31. {
32. for (int i = 0; i < strlen(ch1); i++)//把密钥中的J都变为I
33. {
34. if (ch1[i] == 'J')ch1[i] = 'I';
35. }
36. int i = 0; int j = 0;
37. //把密钥中的字母填入到矩阵中,并把该字母标记为已用
38. for (int k = 0; k < strlen(ch1); k++)
39. {
40. for (int t = 0; t < 25; t++)
41. {
42. if (ch1[k] == letters[t] && flag[t] == 0)
43. {
44. ch[i][j] = letters[t];
45. flag[t] = 1;
46. if (j < 4)j++;
47. else { i++; j = 0; }
48. }
49. }
50. }
51. for (int k = 0; k < 25; k++)//按字母表顺序把未用字母依次填入到矩阵中
52. {
53. if (flag[k] == 0)
54. {
55. ch[i][j] = letters[k];
56. flag[k] = 1;
57. if (j < 4)j++;
58. else { i++; j = 0; }
59. }
60. }
61. cout << "密钥填充后的矩阵为: " << endl;
62. for (i = 0; i < 5; i++)
63. for (j = 0; j < 5; j++)
64. {
65. cout << ch[i][j];
66. cout << " ";
67. if (j == 4)
68. cout << endl;
69. }
70. cout << endl;
71. cout << "请输入明文(请输入英文字符):";
72. cin >> ch2;
73. cout << "输入一个无关字符:";
74. cin >> ch4;
75. if (ch4 >= 'a')
76. ch4 = ch4 - len;
77. for (int k = 0; k < strlen(ch2); k++)//把所输入的明文转化为大写字母
78. {
79. if (ch2[k] >= 'a')
80. ch2[k] = ch2[k] - len;
81. }
82. for (int k = 0; k < strlen(ch2); k++)//把明文中的J都变为I
83. {
84. if (ch2[k] == 'J')
85. ch2[k] = 'I';
86. }
87. //为明文添加必要的无关字符以防止同一组的两个字符相同
88. for (int k = 0; k < strlen(ch2); k += 2)
89. {
90. if (ch2[k] == ch2[k + 1])
91. {
92. for (int t = strlen(ch2); t > k; t--)
93. ch2[t + 1] = ch2[t];
94. ch2[k + 1] = ch4;
95. }
96. }
97. //若明文有奇数个字符,则添加一个无关字符以凑够偶数个
98. if (strlen(ch2) % 2 != 0)
99. {
100. ch2[strlen(ch2) + 1] = ch2[strlen(ch2)];//字符串结尾赋'\0'
101. ch2[strlen(ch2)] = ch4;//明文串尾插入无关字符
102. }
103. cout << "经过处理后的明文为:";
104. for (int k = 0; k < strlen(ch2); k += 2)
105. cout << ch2[k] << ch2[k + 1] << " ";
106. cout << endl;
107. cout << "其最终长度为:" << strlen(ch2) << endl;
108. //明文输入并整理完毕///
109. for (int k = 0; k < strlen(ch2); k += 2)
110. {
111. int m1, m2, n1, n2;
112. for (m1 = 0; m1 <= 4; m1++)
113. {
114. for (n1 = 0; n1 <= 4; n1++)
115. {
116. if (ch2[k] == ch[m1][n1])break;
117. }
118. if (ch2[k] == ch[m1][n1])break;
119. }
120. for (m2 = 0; m2 <= 4; m2++)
121. {
122. for (n2 = 0; n2 <= 4; n2++)
123. {
124. if (ch2[k + 1] == ch[m2][n2])break;
125. }
126. if (ch2[k + 1] == ch[m2][n2])break;
127. }
128. m1 = m1 % 5;
129. m2 = m2 % 5;
130. if (n1 > 4) { n1 = n1 % 5; m1 = m1 + 1; }
131. if (n2 > 4) { n2 = n2 % 5; m2 = m2 + 1; }
132. if (m1 == m2)
133. {
134. ch2[k] = ch[m1][(n1 + 1) % 5];
135. ch2[k + 1] = ch[m2][(n2 + 1) % 5];
136. }
137. else
138. {
139. if (n1 == n2)
140. {
141. ch2[k] = ch[(m1 + 1) % 5][n1];
142. ch2[k + 1] = ch[(m2 + 1) % 5][n2];
143. }
144. else
145. {
146. ch2[k] = ch[m1][n2];
147. ch2[k + 1] = ch[m2][n1];
148. }
149. }
150. }
151. cout << "加密后所得到的密文是:";
152. for (int k = 0; k < strlen(ch2); k += 2)
153. cout << ch2[k] << ch2[k + 1] << " ";
154. cout << endl;
155. }
156. else break;
157. }
158.
159.}
160.
161.//解密算法
162.void decrypt()
163.{
164. const int N = 100;
165. char letters[26] = "ABCDEFGHIKLMNOPQRSTUVWXYZ";//用于填充矩阵
166. int flag[25] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
167. //标记字母是否已在矩阵中,与letters数组对应
168. char ch[5][5];//5X5矩阵
169. char ch1[N];//密钥
170. char ch2[N];//密文
171. int len = 'a' - 'A';
172. int flg = 1;
173. cout << "输入密钥:";
174. cin >> ch1;
175. while (flg == 1)
176. {
177. for (int i = 0; i < strlen(ch1); i++)//把所输入的密钥转化为大写字母
178. {
179. if (ch1[i] > 'z' || ch1[i] < 'a')
180. {
181. cout << "请重新选择操作:" << endl;
182. flg = 0; break;
183. }
184. else
185. ch1[i] = ch1[i] - len;
186. }
187. if (flg == 1)
188. {
189. for (int i = 0; i < strlen(ch1); i++)//把密钥中的J都变为I
190. {
191. if (ch1[i] == 'J')ch1[i] = 'I';
192. }
193. int i = 0; int j = 0;
194. //把密钥中的字母填入到矩阵中,并把该字母标记为已用
195. for (int k = 0; k < strlen(ch1); k++)
196. {
197. for (int t = 0; t < 25; t++)
198. {
199. if (ch1[k] == letters[t] && flag[t] == 0)
200. {
201. ch[i][j] = letters[t];
202. flag[t] = 1;
203. if (j < 4)j++;
204. else { i++; j = 0; }
205. }
206. }
207. }
208. for (int k = 0; k < 25; k++)//按字母表顺序把未用字母依次填入到矩阵中
209. {
210. if (flag[k] == 0)
211. {
212. ch[i][j] = letters[k];
213. flag[k] = 1;
214. if (j < 4)j++;
215. else { i++; j = 0; }
216. }
217. }
218. cout << "密钥填充后的矩阵为: " << endl;
219. for (i = 0; i < 5; i++)
220.
221. for (j = 0; j < 5; j++)
222. {
223. cout << ch[i][j];
224. cout << " ";
225. if (j == 4)
226. cout << endl;
227. }
228. cout << endl;
229. // 矩阵生成完毕
230. int f = 0;
231. do {
232. cout << "请输入密文(英文字符):";
233. cin >> ch2;
234. for (int k = 0; k < strlen(ch2); k++)//把所输入的密文转化为大写字母
235. {
236. if (ch2[k] >= 'a')
237. ch2[k] = ch2[k] - len;
238. }
239. for (int k = 0; k < strlen(ch2); k++)//把密文中的J都变为I
240. {
241. if (ch2[k] == 'J')ch2[k] = 'I';
242. }
243. for (int k = 0; k < strlen(ch2); k += 2)
244. {
245. if (ch2[k] == ch2[k + 1])
246. {
247. cout << "同一分组中不能出现相同字符!请重新输入。" << endl;
248. f = 1;
249. break;
250. }
251. else f = 2;
252. }
253. if (f == 1)continue;
254. if (strlen(ch2) % 2 != 0)
255. {
256. cout << "字符串不能为奇数个!请重新输入。" << endl;
257. f = 1;
258. }
259. else f = 2;
260. } while (f == 1);
261. //解密开始
262. for (int k = 0; k < strlen(ch2); k += 2)
263. {
264. int m1, m2, n1, n2;
265. for (m1 = 0; m1 <= 4; m1++)
266. {
267. for (n1 = 0; n1 <= 4; n1++)
268. {
269. if (ch2[k] == ch[m1][n1])break;
270. }
271. if (ch2[k] == ch[m1][n1])break;
272. }
273. for (m2 = 0; m2 <= 4; m2++)
274. {
275. for (n2 = 0; n2 <= 4; n2++)
276. {
277. if (ch2[k + 1] == ch[m2][n2])break;
278. }
279. if (ch2[k + 1] == ch[m2][n2])break;
280. }
281. m1 = m1 % 5;
282. m2 = m2 % 5;
283. if (n1 > 4) { n1 = n1 % 5; m1 = m1 + 1; }
284. if (n2 > 4) { n2 = n2 % 5; m2 = m2 + 1; }
285. if (m1 == m2)
286. {
287. ch2[k] = ch[m1][(n1 + 4) % 5];
288. ch2[k + 1] = ch[m2][(n2 + 4) % 5];
289. }
290. else
291. {
292. if (n1 == n2)
293. {
294. ch2[k] = ch[(m1 + 4) % 5][n1];
295. ch2[k + 1] = ch[(m2 + 4) % 5][n2];
296. }
297. else
298. {
299. ch2[k] = ch[m1][n2];
300. ch2[k + 1] = ch[m2][n1];
301. }
302. }
303. }
304. cout << "解密后所得到的明文是:";
305. for (int k = 0; k < strlen(ch2); k += 2)
306. cout << ch2[k] << ch2[k + 1] << " ";
307. cout << endl;
308. }
309. else break;
310. }
311.
312.}
313.
314.int main()
315.{
316.
317. int n;
318. cout << "请选择1加密2解密:" << endl;
319. while (true)
320. {
321. cin >> n;
322. switch (n)
323. {
324. case 1:
325. encrypt();
326. break;
327. case 2:
328. decrypt();
329. break;
330. default:
331. break;
332. }
333. }
334. return 0;
335.}
336.
三、Given the plain text{000102030405060708090A0B0C0D0E0F} and the key {010101010101010101010101010101011}:
a. Show the original contents of State, displayed as a 4 x 4 matrix.
00 01 02 03
04 05 06 07
08 09 0A 0B
0C 0D 0E 0F
b. Show the value of State after initial AddRoundKey.
01 00 03 02
05 04 07 06
09 08 0B 0A
0D 0C 0F 0E
c. Show the value of State after SubBytes.
7C 63 7B 77
6B F2 C5 6F
01 30 2B 67
D7 FE 76 AB
d. Show the value of State after ShiftRows.
7C 63 7B 77
F2 C5 6F 6B
2B 67 01 30
AB D7 FE 76
e. Show the value of State after MixColumns.
95 A2 B8 15
B5 0C 58 87
7E AA EF E6
50 12 E4 2E
#include<iostream>
1.using namespace std;
2.int StateMatrix[4][4]; // 状态矩阵
3.#define SIZE_M 4
4.#define SIZE_N 4
5.
6.int muti(int hex1, int hex2) {
7.
8. switch (hex1) {
9. case 0x01:
10. return hex2;
11. case 0x02:
12. if (hex2 >= 0x80) {
13. hex2 = hex2 << 1;
14. hex2 = hex2 % 32;
15. hex2 ^= 0x1b;
16. }
17.
18. else {
19. hex2 = hex2 << 1;
20. //hex2 = hex2 %16;
21. }
22.
23. return hex2;
24. case 0x03:
25. return muti(0x01, hex2) ^ muti(0x02, hex2);
26.
27. }
28. printf("出错啦!");
29. return -1;
30.
31.}
32.
33.int main() {
34.
35. //int matrix_a[SIZE_M][SIZE_N] = { {0x02,0x03,0x01,0x01},{0x01,0x02,0x03,0x01},{0x01,0x01,0x02,0x03},{0x03,0x01,0x01,0x02} };//a
36. //int matrix_b[SIZE_N][SIZE_S] = { {0x7C,0x63,0x7B,0x77},{0xF2,0xC5,0x6F,0x6B},{0x2B,0x67,0x01,0x30},{0xAB,0xD7,0xFE,0x76 } };//b
37.
38.
39. int input[SIZE_M][SIZE_N]= { {0x7C,0x63,0x7B,0x77},{0xF2,0xC5,0x6F,0x6B},{0x2B,0x67,0x01,0x30},{0xAB,0xD7,0xFE,0x76 } };
40.
41.
42.
43. for (int i = 0; i < 4; i++)
44.
45.
46. for (int j = 0; j < 4; j++) {
47.
48. StateMatrix[i][j] = input[i][j];
49.
50. }
51.
52.
53. int d0, d1, d2, d3;
54.
55. for (int i = 0; i < 4; i++) {
56.
57. d0 = muti(0x02, StateMatrix[0][i]) ^ muti(0x03, StateMatrix[1][i]);
58.
59. d0 ^= muti(0x01, StateMatrix[2][i]) ^ muti(0x01, StateMatrix[3][i]);
60.
61. d1 = muti(0x01, StateMatrix[0][i]) ^ muti(0x02, StateMatrix[1][i]);
62.
63.
64. d1 ^= muti(0x03, StateMatrix[2][i]) ^ muti(0x01, StateMatrix[3][i]);
65.
66.
67. d2 = muti(0x01, StateMatrix[0][i]) ^ muti(0x01, StateMatrix[1][i]);
68.
69. d2 ^= muti(0x02, StateMatrix[2][i]) ^ muti(0x03, StateMatrix[3][i]);
70.
71.
72. d3 = muti(0x03, StateMatrix[0][i]) ^ muti(0x01, StateMatrix[1][i]);
73.
74.
75. d3 ^= muti(0x01, StateMatrix[2][i]) ^ muti(0x02, StateMatrix[3][i]);
76.
77.
78. printf("第%d列的结果是:\n%x %x %x %x\n", i, d0, d1, d2, d3);
79.
80. StateMatrix[0][i] = d0;
81.
82. StateMatrix[1][i] = d1;
83.
84. StateMatrix[2][i] = d2;
85.
86. StateMatrix[3][i] = d3;
87.
88. }
89.
90. return 0;
91.
92.}
93.
四、Compute the output of the MixColumns transformation for the following sequence of input bytes “67 89 AB CD.” Apply the InvMixColumns transformation to the obtained result to verify your calculations. Change the first byte of the input from “67” to “77" perform the MixColumns transformation again for the new input, and determine how many bits have changed in the output.
Note: You can perform all calculations by hand or write a program supporting these computations. If you choose to write a program, it should be written entirely by you;no use of libraries or public domain source code is allowed in this assignment.
28 05 2F 8A
08 15 3F BA