当前位置:   article > 正文

【加密】DES加密算法中,ECB和CBC模式有什么区别?_ecb cbc

ecb cbc

目录

ECB和CBC模式的区别

ECB模式

CBC模式:

AES五种加密模式(CBC、ECB、CTR、OCF、CFB)

ECB (Electronic Codebook Book电码本模式)

CBC(Cipher Block Chaining 密码分组链接模式)

C++源代码 


ECB和CBC模式的区别

ECB模式


 ECB(电子密本方式)其实非常简单,就是将数据按照8个字节一段进行DES加密或解密得到一段段的8个字节的密文或者明文,最后一段不足8个字节(一般补0或者F),按照需求补足8个字节进行计算(并行计算),之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。

优点:

  1. 简单;
  2. 有利于并行计算;
  3. 误差不会被传递;

缺点:

  1. 不能隐藏明文的模式;
  2. 可能对明文进行主动攻击;

CBC模式:


优点:

  1. 不容易主动攻击,安全性好于ECB,是SSL、IPSec的标准;

缺点:

  1. 不利于并行计算;
  2. 误差传递;
  3. 需要初始化向量IV;

 CBC(密文分组链接方式)有点麻烦,它的实现机制使加密的各段数据之间有了联系。其实现的机理如下:
加密步骤如下:

  1. 首先将数据按照8个字节一组进行分组得到D1D2…Dn(若数据不是8的整数倍,用指定的PADDING数据补位)
  2. 第一组数据D1与初始化向量I异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)
  3. 第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
  4. 之后的数据以此类推,得到Cn
  5. 按顺序连为C1C2C3…Cn即为加密结果。


原文链接:https://blog.csdn.net/honeygirl_/article/details/90716328

AES五种加密模式(CBC、ECB、CTR、OCF、CFB)

分组密码有五种工作体制:1.电码本模式(Electronic Codebook Book (ECB));2.密码分组链接模式(Cipher Block Chaining (CBC));3.计算器模式(Counter (CTR));4.密码反馈模式(Cipher FeedBack (CFB));5.输出反馈模式(Output FeedBack (OFB))。

以下逐一介绍一下:

ECB (Electronic Codebook Book电码本模式)

    这种模式是将整个明文分成若干段相同的小段,然后对每一小段进行加密。

 

CBC(Cipher Block Chaining 密码分组链接模式)

    这种模式是先将明文切分成若干小段,然后每一小段与初始块(IV)或者上一段的密文段进行异或,再与密钥进行加密。

 

 初始化向量

    当加密第一个明文分组时,由于不存在“前一个密文分组”,因此需要事先准备一个长度为一个分组的比特序列来代替“前一个密文分组”,这个比特序列称为初始化向量(Initialization Vector),通常缩写为IV,一般来说,每次加密时都会随机产生一个不同的比特序列来作为初始化向量。

我们来比较一下ECB模式与CBC模式的区别

 

 ECB模式只进行了加密,而CBC模式则在加密之前进行了一次XOR。

3.计算器模式(Counter (CTR))

        计算器模式不常见,在CTR模式中, 有一个自增的算子,这个算子用密钥加密之后的输出和明文异或的结果得到密文,相当于一次一密。这种加密方式简单快速,安全可靠,而且可以并行加密,但是在计算器不能维持很长的情况下,密钥只能使用一次。CTR的示意图如下所示:

 

 

4.密码反馈模式(Cipher FeedBack (CFB))

    这种模式较复杂。

 12232528-c5c4946255a849379be143aaca8d1ecf.png

5.输出反馈模式(Output FeedBack (OFB))

    这种模式较复杂。

C++源代码 

  1. /**
  2. *@autho stardust
  3. *@time 2013-10-10
  4. *@param 实现AES五种加密模式的测试
  5. */
  6. #include <iostream>
  7. using namespace std;
  8. //加密编码过程函数,16位1和0
  9. int dataLen = 16; //需要加密数据的长度
  10. int encLen = 4; //加密分段的长度
  11. int encTable[4] = {1,0,1,0}; //置换表
  12. int data[16] = {1,0,0,1,0,0,0,1,1,1,1,1,0,0,0,0}; //明文
  13. int ciphertext[16]; //密文
  14. //切片加密函数
  15. void encode(int arr[])
  16. {
  17. for(int i=0;i<encLen;i++)
  18. {
  19. arr[i] = arr[i] ^ encTable[i];
  20. }
  21. }
  22. //电码本模式加密,4位分段
  23. void ECB(int arr[])
  24. {
  25. //数据明文切片
  26. int a[4][4];
  27. int dataCount = 0; //位置变量
  28. for(int k=0;k<4;k++)
  29. {
  30. for(int t=0;t<4;t++)
  31. {
  32. a[k][t] = data[dataCount];
  33. dataCount++;
  34. }
  35. }
  36. dataCount = 0;//重置位置变量
  37. for(int i=0;i<dataLen;i=i+encLen)
  38. {
  39. int r = i/encLen;//行
  40. int l = 0;//列
  41. int encQue[4]; //编码片段
  42. for(int j=0;j<encLen;j++)
  43. {
  44. encQue[j] = a[r][l];
  45. l++;
  46. }
  47. encode(encQue); //切片加密
  48. //添加到密文表中
  49. for(int p=0;p<encLen;p++)
  50. {
  51. ciphertext[dataCount] = encQue[p];
  52. dataCount++;
  53. }
  54. }
  55. cout<<"ECB加密的密文为:"<<endl;
  56. for(int t1=0;t1<dataLen;t1++) //输出密文
  57. {
  58. if(t1!=0 && t1%4==0)
  59. cout<<endl;
  60. cout<<ciphertext[t1]<<" ";
  61. }
  62. cout<<endl;
  63. cout<<"---------------------------------------------"<<endl;
  64. }
  65. //CBC
  66. //密码分组链接模式,4位分段
  67. void CCB(int arr[])
  68. {
  69. //数据明文切片
  70. int a[4][4];
  71. int dataCount = 0; //位置变量
  72. for(int k=0;k<4;k++)
  73. {
  74. for(int t=0;t<4;t++)
  75. {
  76. a[k][t] = data[dataCount];
  77. dataCount++;
  78. }
  79. }
  80. dataCount = 0;//重置位置变量
  81. int init[4] = {1,1,0,0}; //初始异或运算输入
  82. //初始异或运算
  83. for(int i=0;i<dataLen;i=i+encLen)
  84. {
  85. int r = i/encLen;//行
  86. int l = 0;//列
  87. int encQue[4]; //编码片段
  88. //初始化异或运算
  89. for(int k=0;k<encLen;k++)
  90. {
  91. a[r][k] = a[r][k] ^ init[k];
  92. }
  93. //与Key加密的单切片
  94. for(int j=0;j<encLen;j++)
  95. {
  96. encQue[j] = a[r][j];
  97. }
  98. encode(encQue); //切片加密
  99. //添加到密文表中
  100. for(int p=0;p<encLen;p++)
  101. {
  102. ciphertext[dataCount] = encQue[p];
  103. dataCount++;
  104. }
  105. //变换初始输入
  106. for(int t=0;t<encLen;t++)
  107. {
  108. init[t] = encQue[t];
  109. }
  110. }
  111. cout<<"CCB加密的密文为:"<<endl;
  112. for(int t1=0;t1<dataLen;t1++) //输出密文
  113. {
  114. if(t1!=0 && t1%4==0)
  115. cout<<endl;
  116. cout<<ciphertext[t1]<<" ";
  117. }
  118. cout<<endl;
  119. cout<<"---------------------------------------------"<<endl;
  120. }
  121. //CTR
  122. //计算器模式,4位分段
  123. void CTR(int arr[])
  124. {
  125. //数据明文切片
  126. int a[4][4];
  127. int dataCount = 0; //位置变量
  128. for(int k=0;k<4;k++)
  129. {
  130. for(int t=0;t<4;t++)
  131. {
  132. a[k][t] = data[dataCount];
  133. dataCount++;
  134. }
  135. }
  136. dataCount = 0;//重置位置变量
  137. int init[4][4] = {{1,0,0,0},{0,0,0,1},{0,0,1,0},{0,1,0,0}}; //算子表
  138. int l = 0; //明文切片表列
  139. //初始异或运算
  140. for(int i=0;i<dataLen;i=i+encLen)
  141. {
  142. int r = i/encLen;//行
  143. int encQue[4]; //编码片段
  144. //将算子切片
  145. for(int t=0;t<encLen;t++)
  146. {
  147. encQue[t] = init[r][t];
  148. }
  149. encode(encQue); //算子与key加密
  150. //最后的异或运算
  151. for(int k=0;k<encLen;k++)
  152. {
  153. encQue[k] = encQue[k] ^ a[l][k];
  154. }
  155. l++;
  156. //添加到密文表中
  157. for(int p=0;p<encLen;p++)
  158. {
  159. ciphertext[dataCount] = encQue[p];
  160. dataCount++;
  161. }
  162. }
  163. cout<<"CTR加密的密文为:"<<endl;
  164. for(int t1=0;t1<dataLen;t1++) //输出密文
  165. {
  166. if(t1!=0 && t1%4==0)
  167. cout<<endl;
  168. cout<<ciphertext[t1]<<" ";
  169. }
  170. cout<<endl;
  171. cout<<"---------------------------------------------"<<endl;
  172. }
  173. //CFB
  174. //密码反馈模式,4位分段
  175. void CFB(int arr[])
  176. {
  177. //数据明文切片,切成2 * 8 片
  178. int a[8][2];
  179. int dataCount = 0; //位置变量
  180. for(int k=0;k<8;k++)
  181. {
  182. for(int t=0;t<2;t++)
  183. {
  184. a[k][t] = data[dataCount];
  185. dataCount++;
  186. }
  187. }
  188. dataCount = 0; //恢复初始化设置
  189. int lv[4] = {1,0,1,1}; //初始设置的位移变量
  190. int encQue[2]; //K的高两位
  191. int k[4]; //K
  192. for(int i=0;i<2 * encLen;i++) //外层加密循环
  193. {
  194. //产生K
  195. for(int vk=0;vk<encLen;vk++)
  196. {
  197. k[vk] = lv[vk];
  198. }
  199. encode(k);
  200. for(int k2=0;k2<2;k2++)
  201. {
  202. encQue[k2] = k[k2];
  203. }
  204. //K与数据明文异或产生密文
  205. for(int j=0;j<2;j++)
  206. {
  207. ciphertext[dataCount] = a[dataCount/2][j] ^ encQue[j];
  208. dataCount++;
  209. }
  210. //lv左移变换
  211. lv[0] = lv[2];
  212. lv[1] = lv[3];
  213. lv[2] = ciphertext[dataCount-2];
  214. lv[3] = ciphertext[dataCount-1];
  215. }
  216. cout<<"CFB加密的密文为:"<<endl;
  217. for(int t1=0;t1<dataLen;t1++) //输出密文
  218. {
  219. if(t1!=0 && t1%4==0)
  220. cout<<endl;
  221. cout<<ciphertext[t1]<<" ";
  222. }
  223. cout<<endl;
  224. cout<<"---------------------------------------------"<<endl;
  225. }
  226. //OFB
  227. //输出反馈模式,4位分段
  228. void OFB(int arr[])
  229. {
  230. //数据明文切片,切成2 * 8 片
  231. int a[8][2];
  232. int dataCount = 0; //位置变量
  233. for(int k=0;k<8;k++)
  234. {
  235. for(int t=0;t<2;t++)
  236. {
  237. a[k][t] = data[dataCount];
  238. dataCount++;
  239. }
  240. }
  241. dataCount = 0; //恢复初始化设置
  242. int lv[4] = {1,0,1,1}; //初始设置的位移变量
  243. int encQue[2]; //K的高两位
  244. int k[4]; //K
  245. for(int i=0;i<2 * encLen;i++) //外层加密循环
  246. {
  247. //产生K
  248. for(int vk=0;vk<encLen;vk++)
  249. {
  250. k[vk] = lv[vk];
  251. }
  252. encode(k);
  253. for(int k2=0;k2<2;k2++)
  254. {
  255. encQue[k2] = k[k2];
  256. }
  257. //K与数据明文异或产生密文
  258. for(int j=0;j<2;j++)
  259. {
  260. ciphertext[dataCount] = a[dataCount/2][j] ^ encQue[j];
  261. dataCount++;
  262. }
  263. //lv左移变换
  264. lv[0] = lv[2];
  265. lv[1] = lv[3];
  266. lv[2] = encQue[0];
  267. lv[3] = encQue[1];
  268. }
  269. cout<<"CFB加密的密文为:"<<endl;
  270. for(int t1=0;t1<dataLen;t1++) //输出密文
  271. {
  272. if(t1!=0 && t1%4==0)
  273. cout<<endl;
  274. cout<<ciphertext[t1]<<" ";
  275. }
  276. cout<<endl;
  277. cout<<"---------------------------------------------"<<endl;
  278. }
  279. void printData()
  280. {
  281. cout<<"以下示范AES五种加密模式的测试结果:"<<endl;
  282. cout<<"---------------------------------------------"<<endl;
  283. cout<<"明文为:"<<endl;
  284. for(int t1=0;t1<dataLen;t1++) //输出密文
  285. {
  286. if(t1!=0 && t1%4==0)
  287. cout<<endl;
  288. cout<<data[t1]<<" ";
  289. }
  290. cout<<endl;
  291. cout<<"---------------------------------------------"<<endl;
  292. }
  293. int main()
  294. {
  295. printData();
  296. ECB(data);
  297. CCB(data);
  298. CTR(data);
  299. CFB(data);
  300. OFB(data);
  301. return 0;
  302. }

原文:AES五种加密模式(CBC、ECB、CTR、OCF、CFB) - 月之星狼 - 博客园

四 对CBC模式的攻击

假设主动攻击者的目的是通过修改密文来操纵解密后的明文。如果攻击者能够对初始化向量中的任意比特进行反转(将1变成0,将0变成1),则明文分组中相应的比特也会被反转。这是因为在CBC模式的解密过程中,第一个明文分组会和初始化向量进行XOR运算。见下图。

 

 但是想对密文分组也进行同样的攻击就非常困难了。例如,如果攻击者将密文分组1中的某个比特进行反转,则明文分组2中相应比特也会被反转,然而这一比特的变化却对解密后的明文分组1中的多个比特造成了影响,也就是说,只让明文分1中所期望的特定比特发生变化是很困难的。

五 填充提示攻击

填充提示攻击是一种利用分组密码中填充部分来进行攻击的方法。在分组密码中,当明文长度不为分组长度的整数倍时,需要在最后一个分组中填充一些数据使其凑满一个分组长度。在填充提示攻击中,攻击者会反复发送一段密文,每次发送时都对填充数据进行少许改变。由于接收者(服务器)在无法正确解密时会返回一个错误消息,攻击者通过这一错误消息就可以获得一部分与明文相关的信息。这一攻击并不仅限于CBC模式,而是适用所有需要进行分组填充的模式。

2014年对SSL3.0 造成了重大影响POODLE攻击实际上就是一种填充示攻击。

六 对初始化向量(IV)进行攻击

初始化向量(IV)必须使用不可预测的随机数。然而在SSL/TLS的TLS1.0版本协议中,IV并没有使用不可预测的随机数,而是使用上一次CBC模式加密时的最后一个分组。为了防御攻击者对此进行攻击,TLS1.1以上的版本中改为了必须显示传送IV。

七 CBC模式应用

确保互联网安全的通信协议之一SSL/TLS,就是使用CBC模式来确保通信机密性的,如使用CBC模式三重DES的3DES_EDE_CBC以及CBC模式256比特AES的AES_256_CBC等。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/1016873
推荐阅读
相关标签
  

闽ICP备14008679号