AES是美国国家标准技术研究所NIST旨在取代DES的21世纪的加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。1998年NIST开始AES第一轮分析、测试和征集,共产生了15个候选算法。1999年3月完成了第二轮AES的分析、测试。2000年10月2日美国政府正式宣布选中比利时密码学家Joan Daemen 和 Vincent Rijmen 提出的一种密码算法RIJNDAEL 作为 AES。高级加密标准由NIST于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。

AES加密数据块分组长度必须为128比特,密钥长度可以是128比特、192比特、256比特中的任意一个(如果数据块及密钥长度不足时,会补齐),分别称为AES-128、AES-192和AES-256。AES加密有很多轮的重复和变换。大致步骤如下:1、密钥扩展(KeyExpansion),2、初始轮(Initial Round),3、重复轮(Rounds),每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,4、最终轮(Final Round),最终轮没有MixColumns。

Crypto++库很好的一点是,不用我们手动的对明文块或者密文块进行分组,而是在实现中自动完成了,这样就减少了我们的工作量。

 

等等,那AES在分组的时候,有没有什么标准?难道只是将需要加密的信息分成128bit的一块块吗?事实上不是这个样子的。AES作为分组密码的一种,而分组密码从DES时代起就拥有了很多种的工作模式。下面简要介绍各种模式。(部分文字及图片来自维基百科)

(1) ECB模式

最简单的加密模式即为电子密码本(Electronic codebook,ECB)模式。需要加密的消息按照块密码的块大小被分为数个块,并对每个块进行独立加密。简单的理解,ECB模式就是将很长的明文,按照128bit分组,不足补零。每组用相同密钥进行加密,最后将各组密文拼在一起即可。就是分割处理的想法,各个不同的明文块和密文块之间没有运算关系。

ECB模式的优点是可并行运算,速度快,易于标准化。缺点是分组加密不能隐蔽数据模式,即相同的明文组蕴含着相同的密文组;不能抵抗组的重放、嵌入、删除等攻击;加密长度只能是分组的倍数。


Python aes解密 密钥偏移量 python crypto aes_bc

(2) CBC模式

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


Python aes解密 密钥偏移量 python crypto aes_ci_02

(3) CFB

密文反馈(CFB,Cipherfeedback)模式类似于CBC,可以将块密码变为自同步的流密码;工作过程亦非常相似,CFB的解密过程几乎就是颠倒的CBC的加密过程。


Python aes解密 密钥偏移量 python crypto aes_ci_03

(4)OFB

输出反馈模式(Outputfeedback, OFB)可以将块密码变成同步的流密码。它产生密钥流的块,然后将其与明文块进行异或,得到密文。与其它流密码一样,密文中一个位的翻转会使明文中同样位置的位也产生翻转。这种特性使得许多错误校正码,例如奇偶校验位,即使在加密前计算而在加密后进行校验也可以得出正确结果。由于XOR操作的对称性,加密和解密操作是完全相同的。


Python aes解密 密钥偏移量 python crypto aes_#include_04

(5)CTR

与OFB相似,CTR将块密码变为流密码。它通过递增一个加密计数器以产生连续的密钥流,其中,计数器可以是任意保证不产生长时间重复输出的函数,但使用一个普通的计数器是最简单和最常见的做法。CTR模式的特征类似于OFB,但它允许在解密时进行随机存取。由于加密和解密过程均可以进行并行处理,CTR适合运用于多处理器的硬件上。

注意图中的“nonce(随机数)”与其它图中的IV(初始化向量)相同。IV、随机数和计数器均可以通过连接,相加或异或使得相同平文产生不同的密文。


Python aes解密 密钥偏移量 python crypto aes_#include_05

(6)CBC_CTS

即应用了密文窃取(Ciphertextstealing)技术的CBC。

我们在上面的介绍中可以注意到,ECB和CBC两种模式,其输出密文长度永远都是分块大小(128bits)的整数倍,而其他模式都是和输入明文等长。为了解决输出密文偏长的情况,就可以采用密文窃取方式。CBC_CTS具体过程如下:

加密过程:

a.      Xn−1 = Pn−1XOR Cn−2.

b.      En−1 = Encrypt (K, Xn−1).

c.      Cn = Head (En−1,M).

d.      P = Pn || 0B−M.

e.      Dn = En−1XOR P.

f.       Cn−1 = Encrypt (K, Dn).

解密过程:

a.      Dn = Decrypt (K, Cn−1).

b.      C = Cn || 0B−M.

c.      Xn = DnXOR C.

d.      Pn = Head (Xn,M).

e.      En−1 = Cn|| Tail (Xn, B−M).

f.       Xn−1 = Decrypt (K, En−1).

g.      Pn−1 = Xn−1XOR Cn−2.

下面是我绘制的示意图。


Python aes解密 密钥偏移量 python crypto aes_ci_06


 

 

按照上文所述,对建立的Win32控制台应用程序进行必要的配置之后(在上篇文章中),就可以开始写程序了。下面就是完成的AES程序。该程序可以去我的资源中找到。


[cpp]  view plain copy


1. // aestest2.cpp : 定义控制台应用程序的入口点。  
2. //  
3.   
4. #include "stdafx.h"  
5. #include <aes.h>  
6. #include <cryptopp/Hex.h>      // StreamTransformationFilter  
7. #include <cryptopp/modes.h>    // CFB_Mode  
8. #include <iostream>              // std:cerr    
9. #include <sstream>               // std::stringstream    
10. #include <string>  
11.   
12. using namespace std;  
13. using namespace CryptoPP;  
14. #pragma comment( lib, "cryptlib.lib" )  
15.   
16.   
17.   
18. std::string ECB_AESEncryptStr(std::string sKey, const char *plainText)  
19. {  
20.     std::string outstr;  
21.         
22. //填key    
23.     SecByteBlock key(AES::MAX_KEYLENGTH);    
24.     memset(key,0x30,key.size() );    
25.     sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);    
26.             
27.         
28.     AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);    
29.         
30.     ECB_Mode_ExternalCipher::Encryption ecbEncryption(aesEncryption);  
31. new HexEncoder(new StringSink(outstr)));    
32.     ecbEncryptor.Put((byte *)plainText, strlen(plainText));    
33.     ecbEncryptor.MessageEnd();    
34.         
35. return outstr;    
36. }    
37.   
38.   
39. std::string ECB_AESDecryptStr(std::string sKey, const char *cipherText)    
40. {    
41.     std::string outstr;    
42.         
43. //填key    
44.     SecByteBlock key(AES::MAX_KEYLENGTH);    
45.     memset(key,0x30,key.size() );    
46.     sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);    
47.             
48.     ECB_Mode<AES >::Decryption ecbDecryption((byte *)key, AES::MAX_KEYLENGTH);    
49.             
50. new StreamTransformationFilter(ecbDecryption, new StringSink(outstr)));    
51.     decryptor.Put((byte *)cipherText, strlen(cipherText));    
52.     decryptor.MessageEnd();    
53.         
54. return outstr;    
55. }    
56.   
57.   
58. std::string CBC_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText)  
59. {  
60.     std::string outstr;  
61.         
62. //填key    
63.     SecByteBlock key(AES::MAX_KEYLENGTH);    
64.     memset(key,0x30,key.size() );    
65.     sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);    
66.             
67. //填iv    
68.     byte iv[AES::BLOCKSIZE];    
69.     memset(iv,0x30,AES::BLOCKSIZE);   
70.     sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);  
71.         
72.     AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);    
73.         
74.     CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv);    
75.         
76. new HexEncoder(new StringSink(outstr)));    
77.     cbcEncryptor.Put((byte *)plainText, strlen(plainText));    
78.     cbcEncryptor.MessageEnd();    
79.         
80. return outstr;    
81. }    
82.   
83.   
84. std::string CBC_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText)    
85. {    
86.     std::string outstr;    
87.         
88. //填key    
89.     SecByteBlock key(AES::MAX_KEYLENGTH);    
90.     memset(key,0x30,key.size() );    
91.     sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);    
92.             
93. //填iv    
94.     byte iv[AES::BLOCKSIZE];    
95.     memset(iv,0x30,AES::BLOCKSIZE);    
96.     sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);  
97.   
98.     CBC_Mode<AES >::Decryption cbcDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);    
99.             
100. new StreamTransformationFilter(cbcDecryption, new StringSink(outstr)));    
101.     decryptor.Put((byte *)cipherText, strlen(cipherText));    
102.     decryptor.MessageEnd();    
103.         
104. return outstr;    
105. }    
106.   
107.   
108. std::string CBC_CTS_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText)  
109. {  
110.     std::string outstr;  
111.         
112. //填key    
113.     SecByteBlock key(AES::MAX_KEYLENGTH);    
114.     memset(key,0x30,key.size() );    
115.     sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);    
116.             
117. //填iv    
118.     byte iv[AES::BLOCKSIZE];    
119.     memset(iv,0x30,AES::BLOCKSIZE);   
120.     sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);  
121.         
122.     AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);    
123.         
124.     CBC_CTS_Mode_ExternalCipher::Encryption cbcctsEncryption(aesEncryption, iv);    
125.         
126. new HexEncoder(new StringSink(outstr)));    
127.     cbcctsEncryptor.Put((byte *)plainText, strlen(plainText));    
128.     cbcctsEncryptor.MessageEnd();    
129.         
130. return outstr;    
131. }    
132.   
133.   
134. std::string CBC_CTS_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText)    
135. {    
136.     std::string outstr;    
137.         
138. //填key    
139.     SecByteBlock key(AES::MAX_KEYLENGTH);    
140.     memset(key,0x30,key.size() );    
141.     sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);    
142.             
143. //填iv    
144.     byte iv[AES::BLOCKSIZE];    
145.     memset(iv,0x30,AES::BLOCKSIZE);    
146.     sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);  
147.   
148.     CBC_CTS_Mode<AES >::Decryption cbcctsDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);    
149.             
150. new StreamTransformationFilter(cbcctsDecryption, new StringSink(outstr)));    
151.     decryptor.Put((byte *)cipherText, strlen(cipherText));    
152.     decryptor.MessageEnd();    
153.         
154. return outstr;    
155. }    
156.   
157.   
158.   
159.   
160.   
161. std::string CFB_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText)  
162. {  
163.     std::string outstr;  
164.         
165. //填key    
166.     SecByteBlock key(AES::MAX_KEYLENGTH);    
167.     memset(key,0x30,key.size() );    
168.     sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);    
169.             
170. //填iv    
171.     byte iv[AES::BLOCKSIZE];    
172.     memset(iv,0x30,AES::BLOCKSIZE);   
173.     sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);  
174.         
175.     AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);    
176.         
177.     CFB_Mode_ExternalCipher::Encryption cfbEncryption(aesEncryption, iv);    
178.         
179. new HexEncoder(new StringSink(outstr)));    
180.     cfbEncryptor.Put((byte *)plainText, strlen(plainText));    
181.     cfbEncryptor.MessageEnd();    
182.         
183. return outstr;    
184. }    
185.   
186.   
187. std::string CFB_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText)    
188. {    
189.     std::string outstr;    
190.         
191. //填key    
192.     SecByteBlock key(AES::MAX_KEYLENGTH);    
193.     memset(key,0x30,key.size() );    
194.     sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);    
195.             
196. //填iv    
197.     byte iv[AES::BLOCKSIZE];    
198.     memset(iv,0x30,AES::BLOCKSIZE);    
199.     sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);  
200.   
201.     CFB_Mode<AES >::Decryption cfbDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);    
202.             
203. new StreamTransformationFilter(cfbDecryption, new StringSink(outstr)));    
204.     decryptor.Put((byte *)cipherText, strlen(cipherText));    
205.     decryptor.MessageEnd();    
206.         
207. return outstr;    
208. }    
209.   
210.   
211. std::string OFB_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText)  
212. {  
213.     std::string outstr;  
214.         
215. //填key    
216.     SecByteBlock key(AES::MAX_KEYLENGTH);    
217.     memset(key,0x30,key.size() );    
218.     sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);    
219.             
220. //填iv    
221.     byte iv[AES::BLOCKSIZE];    
222.     memset(iv,0x30,AES::BLOCKSIZE);   
223.     sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);  
224.         
225.     AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);    
226.         
227.     OFB_Mode_ExternalCipher::Encryption ofbEncryption(aesEncryption, iv);    
228.         
229. new HexEncoder(new StringSink(outstr)));    
230.     ofbEncryptor.Put((byte *)plainText, strlen(plainText));    
231.     ofbEncryptor.MessageEnd();    
232.         
233. return outstr;    
234. }    
235.   
236.   
237. std::string OFB_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText)    
238. {    
239.     std::string outstr;    
240.         
241. //填key    
242.     SecByteBlock key(AES::MAX_KEYLENGTH);    
243.     memset(key,0x30,key.size() );    
244.     sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);    
245.             
246. //填iv    
247.     byte iv[AES::BLOCKSIZE];    
248.     memset(iv,0x30,AES::BLOCKSIZE);    
249.     sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);  
250.   
251.     OFB_Mode<AES >::Decryption ofbDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);    
252.             
253. new StreamTransformationFilter(ofbDecryption, new StringSink(outstr)));    
254.     decryptor.Put((byte *)cipherText, strlen(cipherText));    
255.     decryptor.MessageEnd();    
256.         
257. return outstr;    
258. }    
259.   
260. std::string CTR_AESEncryptStr(std::string sKey, std::string sIV, const char *plainText)  
261. {  
262.     std::string outstr;  
263.         
264. //填key    
265.     SecByteBlock key(AES::MAX_KEYLENGTH);    
266.     memset(key,0x30,key.size() );    
267.     sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);    
268.             
269. //填iv    
270.     byte iv[AES::BLOCKSIZE];    
271.     memset(iv,0x30,AES::BLOCKSIZE);   
272.     sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);  
273.         
274.     AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);    
275.         
276.     CTR_Mode_ExternalCipher::Encryption ctrEncryption(aesEncryption, iv);    
277.         
278. new HexEncoder(new StringSink(outstr)));    
279.     ctrEncryptor.Put((byte *)plainText, strlen(plainText));    
280.     ctrEncryptor.MessageEnd();    
281.         
282. return outstr;    
283. }    
284.   
285.   
286. std::string CTR_AESDecryptStr(std::string sKey, std::string sIV, const char *cipherText)    
287. {    
288.     std::string outstr;    
289.         
290. //填key    
291.     SecByteBlock key(AES::MAX_KEYLENGTH);    
292.     memset(key,0x30,key.size() );    
293.     sKey.size()<=AES::MAX_KEYLENGTH?memcpy(key,sKey.c_str(),sKey.size()):memcpy(key,sKey.c_str(),AES::MAX_KEYLENGTH);    
294.             
295. //填iv    
296.     byte iv[AES::BLOCKSIZE];    
297.     memset(iv,0x30,AES::BLOCKSIZE);    
298.     sIV.size()<=AES::BLOCKSIZE?memcpy(iv,sIV.c_str(),sIV.size()):memcpy(iv,sIV.c_str(),AES::BLOCKSIZE);  
299.   
300.     CTR_Mode<AES >::Decryption ctrDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);    
301.             
302. new StreamTransformationFilter(ctrDecryption, new StringSink(outstr)));    
303.     decryptor.Put((byte *)cipherText, strlen(cipherText));    
304.     decryptor.MessageEnd();    
305.         
306. return outstr;    
307. }    
308.   
309. int _tmain(int argc, _TCHAR* argv[])  
310. {  
311. "This Program shows how to use ECB, CBC, CBC_CTS, CFB, OFB and CTR mode of AES in Crypto++.";  
312. "0123456789ABCDEF0123456789ABCDEF";//256bits, also can be 128 bits or 192bits  
313. "ABCDEF0123456789";//128 bits  
314.     string ECB_EncryptedText,ECB_DecryptedText,  
315.         CBC_EncryptedText,CBC_DecryptedText,  
316.         CBC_CTS_EncryptedText,CBC_CTS_DecryptedText,  
317.         CFB_EncryptedText,CFB_DecryptedText,  
318.         OFB_EncryptedText,OFB_DecryptedText,  
319.         CTR_EncryptedText,CTR_DecryptedText;  
320.   
321. //ECB  
322. //ECB加密  
323. //ECB解密  
324.   
325. //CBC  
326. //CBC加密  
327. //CBC解密  
328.   
329. //CBC_CTS  
330. //CBC_CTS加密  
331. //CBC_CTS解密  
332.       
333. //CFB  
334. //CFB加密  
335. //CFB解密  
336.   
337. //OFB  
338. //OFB加密  
339. //OFB解密  
340.   
341. //CTR  
342. //CTR加密  
343. //CTR解密  
344.   
345.   
346. "Crypto++ AES-256 加密测试"<< endl;  
347. "分别使用ECB,CBC, CBC_CTR,CFB,OFB和CTR模式"<< endl;  
348. "加密用密钥:" << aesKey << endl;  
349. "密钥长度:" << AES::MAX_KEYLENGTH*8 <<"bits" << endl;  
350. "IV:" << aesIV << endl;  
351.     cout << endl;  
352.   
353. "ECB测试"<< endl;  
354. "原文:" << plainText << endl;  
355. "密文:" << ECB_EncryptedText << endl;  
356. "恢复明文:" << ECB_DecryptedText << endl << endl;  
357.       
358. "CBC测试"<< endl;  
359. "原文:" << plainText << endl;  
360. "密文:" << CBC_EncryptedText << endl;  
361. "恢复明文:" << CBC_DecryptedText << endl << endl;  
362.   
363. "CBC_CTS测试"<< endl;  
364. "原文:" << plainText << endl;  
365. "密文:" << CBC_CTS_EncryptedText << endl;  
366. "恢复明文:" << CBC_CTS_DecryptedText << endl << endl;  
367.   
368. "CFB测试"<< endl;  
369. "原文:" << plainText << endl;  
370. "密文:" << CFB_EncryptedText << endl;  
371. "恢复明文:" << CFB_DecryptedText << endl << endl;  
372.       
373. "OFB测试"<< endl;  
374. "原文:" << plainText << endl;  
375. "密文:" << OFB_EncryptedText << endl;  
376. "恢复明文:" << OFB_DecryptedText << endl << endl;  
377.   
378. "CTR测试"<< endl;  
379. "原文:" << plainText << endl;  
380. "密文:" << CTR_EncryptedText << endl;  
381. "恢复明文:" << CTR_DecryptedText << endl << endl;  
382.   
383.   
384.     getchar();  
385. return 0;  
386. }

 

下面是程序运行结果。可以注意一下各种模式输出的密文长度和具体内容。可以发现ECB和CBC输出模式最长(因要补足128比特块),其他模式输出长度和原文一样。各种模式输出均不相同。


Python aes解密 密钥偏移量 python crypto aes_Python aes解密 密钥偏移量_07