虽然AES的ECB加密模式,有简单,利于并行计算,误差不会传输等优点,但是也会有明显的缺点。例如不能隐藏明文的模式,可以对明文进行主动攻击。例如:因为如果采用ECB模式,如果送入的明文是一样的,则得出的密文是一样的。因此可以通过这个,来重复的试出密钥。
因此,可以使用更加难于破解的方式来对明文进行加密。例如采用CBC的方式进行加密。
Cipher Block Chaining(CBC)的第一块讯息B1与初始化向量IV(一个随机数)做XOR之后,再和密钥产生密文C1,之后,每个数据块再不用IV,而用前一块的密文取代。
CBC改善了ECB不适合长明文的缺点,即使有两块相同的明文,也会产生不同的密文。此外,若任一块发生错误,CBC也不会产生错误扩散。
CBC缺点就是完全无法平行处理,必须等待上一块的明文加密算法完成之后,才能对下一块明文进行加密。
具体如下图所示(摘自潘天佑博士《資訊安全概論與實務》):
例程:
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include "efm32.h"
#include "efm32_chip.h"
#include "efm32_cmu.h"
#include "efm32_aes.h"
/***************************************************
该demo主要是使用EFM32片内的AES加解密硬件加速器来实现对
特定字符的加密和解密。
1.使用128bit进行加解密
2.使用CBC方式进行加密
***************************************************/
//初始明文
unsigned char AES_PlantTest1[16] = "This aaaaa text";
//使用该变量来查看加密之后的密文
unsigned char AES_PlantTest2[16];
//使用该变量来查看解密之后的明文
unsigned char AES_PlantTest3[16];
//密钥
unsigned char g_ucKey[16] =
{
0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89,
0x9A, 0xAB, 0xBC, 0xCD, 0xDE, 0xEF, 0xF0, 0x00
};
unsigned char g_ucIV[16] =
{
0x02, 0x23, 0x34, 0xf5, 0x56, 0x99, 0x46, 0x07,
0x55, 0x93, 0xBC, 0xCD, 0x3E, 0x26, 0xF5, 0x88
};
void AES_CBC_XOR(unsigned char *out, unsigned char *In)
{
for(unsigned char i = 0; i < 16; i++)
{
out[i] = out[i] ^ In[i];
}
}
/*********************************************
加密:
1.明文和InitVector(128bit随机数)异或
2.将异或的结果与密钥送入AES进行加密,生成密文
解密:
1.将密文和密钥送入AES解密,然后生成明文
2.将明文再次与InitVector异或,产生最后的明文
*********************************************/
void AES_CBC_128bit_Encrypt(void)
{
AES_CBC_XOR(AES_PlantTest1,g_ucIV);
AES_CBC128(AES_PlantTest2,AES_PlantTest1,16,g_ucKey,g_ucIV,true);
AES_DecryptKey128(g_ucKey,g_ucKey);
AES_CBC128(AES_PlantTest3,AES_PlantTest2,16,g_ucKey,g_ucIV,false);
AES_CBC_XOR(AES_PlantTest3,g_ucIV);
}
int main(void)
{
/* Chip errata */
CHIP_Init();
CMU_ClockEnable(cmuClock_AES,true);
AES_CBC_128bit_Encrypt();
while(1);
}