aes-cbc模式加密

时间:2024-01-30 08:10:32

aes-cbc模式加密——密码分组链接模式(Cipher Block Chaining (CBC))

aes-cbc模式加密在加密和解密是需要一个初始化向量(Initialization Vector, IV),在每次加密之前或者解密之后,使用初始化向量与明文或密文异或。

1. 加密


加密时,明文首先与IV异或,然后将结果进行块加密,得到的输出就是密文,同时本次的输出密文作为下一个块加密的IV。

加密过程代码:

 1 cypher_t* aes_cbc_encrypt(uint8_t* key, cypher_t* data_in)
 2 {
 3     //pad last block with 0
 4     cypher_t* data_in_padding = block_padding(data_in);
 5     cypher_t* cypher_out = (cypher_t*)malloc(sizeof(uint8_t) + data_in->len_data);
 6     cypher_out->len_data = data_in_padding->len_data;
 7 
 8     uint8_t iv[16] = {0};
 9     memcpy(iv, IV, 16);
10     uint8_t temp_out[16] = {0};
11     for (uint8_t index = 0; index < data_in_padding->len_data/16 ; ++index){
12         array_xor(16, temp_out, data_in_padding->data + (index * 16), iv);      //明文与iv异或
13         _aes128_encryption(key, cypher_out->data + index * 16, temp_out);       //进行块加密得到密文,同时密文是下次加密的iv
14         memcpy(iv, cypher_out->data + index * 16, 16);                          //本次的密文是下次加密的iv
15     }
16     free(data_in_padding);
17     return cypher_out;
18 }

2. 解密


解密时,先将密文的第一个块进行块解密,然后将结果与IV异或,就能得到明文,同时,本次解密的输入密文作为下一个块解密的IV。

解密过程代码:

 1 cypher_t* aes_cbc_decrypt(uint8_t* key, cypher_t* data_in)
 2 {
 3     cypher_t* cypher_padding = block_padding(data_in);
 4     cypher_t* plain = (cypher_t*)malloc(data_in->len_data);
 5     plain->len_data = cypher_padding->len_data;
 6     uint8_t iv[16] = {0};
 7     memcpy(iv, IV, 16);
 8     uint8_t temp_out[16] = {0};
 9     for (uint8_t index = 0; index < cypher_padding->len_data/16 ; ++index){
10         _aes128_decryption(key, temp_out, cypher_padding->data + (index*16));   //密文块解密
11         array_xor(16, plain->data + (index*16), temp_out, iv);                  //与iv异或得到明文
12         memcpy(iv, cypher_padding->data + (index*16), 16);                      //设置下次解密用到的iv
13     }
14     free(cypher_padding);
15     return plain;
16 }

测试程序:

 1 int main()
 2 {
 3     uint8_t key[16] = {
 4         0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
 5     };
 6     uint8_t iv[16] = {
 7         0xa, 0xb, 0xc, 0xd, 0x1, 0x2, 0x3, 0x3, 0xa, 0xa, 0xa, 0xa, 0xf, 0xf, 0xf, 0xf
 8     };
 9     uint8_t* text = "hello aes_cbc encryption!";
10 
11     printf("密钥:");
12     for (int i = 0; i < 16; ++i){
13         if (i%4 == 0 && i != 0)
14             printf(" ");
15         if (i % 16 == 0 && i != 0)
16             printf("\n");
17         printf("%02x ", key[i]);
18     }
19     printf("\n");
20     printf("明文:%s\n\n", text);
21 
22     set_iv(iv);
23     //--------------------------aes cbc encrypt--------------------------------------
24     cypher_t* plain = (cypher_t*)malloc(sizeof(uint8_t) + strlen(text));
25     plain->len_data = strlen(text);
26     memcpy(plain->data, text, plain->len_data);
27     cypher_t* cypher = aes_cbc_encrypt(key, plain);
28     puts("密文:");
29     for (int i = 0; i < cypher->len_data; ++i){
30         if (i%4 == 0 && i != 0)
31             printf(" ");
32         if (i % 16 == 0 && i != 0)
33             printf("\n");
34         printf("%02x ", cypher->data[i]);
35 
36     }
37     printf("\n\n");
38     free(plain);
39     //--------------------------aes cbc decrypt--------------------------------------
40     cypher_t* decrypted_plain = aes_cbc_decrypt(key, cypher);
41     puts("解密之后:");
42     for (int i = 0; i < decrypted_plain->len_data; ++i){
43         if (i%4 == 0 && i != 0)
44             printf(" ");
45         if (i % 16 == 0 && i != 0)
46             printf("\n");
47         printf("%02x ", decrypted_plain->data[i]);
48     }
49     printf("\n\n");
50     printf("解密之后的明文字符串输出:\n%s", decrypted_plain);
51     printf("\n\n");
52     free(decrypted_plain);
53     return 0;
54 }

 

输出:

密钥:01 02 03 04 0a 0b 0c 0d 00 00 00 00 ff ff ff ff
明文:hello aes_cbc encryption!

密文:
76 ae bb ed d2 c3 a6 16 00 4a 4b 3b 33 67 96 07
85 7c 70 c5 0b 7e f2 b6 75 ff fc 67 f4 99 c0 8a

解密之后:
68 65 6c 6c 6f 20 61 65 73 5f 63 62 63 20 65 6e
63 72 79 70 74 69 6f 6e 21 00 00 00 00 00 00 00

解密之后的明文字符串输出:
hello aes_cbc encryption!

完整代码在 https://github.com/FANCY0047/aes-cbc.git
注:aes加密解密函数来源于互联网