aes-cbc模式加密

转载  https://www.cnblogs.com/eleven-elv/p/7289579.html

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

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

1. 加密


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

aes-cbc模式加密_第1张图片

加密过程代码:

cypher_t* aes_cbc_encrypt(uint8_t* key, cypher_t* data_in)
{
    //pad last block with 0
    cypher_t* data_in_padding = block_padding(data_in);
    cypher_t* cypher_out = (cypher_t*)malloc(sizeof(uint8_t) + data_in->len_data);
    cypher_out->len_data = data_in_padding->len_data;

    uint8_t iv[16] = {0};
    memcpy(iv, IV, 16);
    uint8_t temp_out[16] = {0};
    for (uint8_t index = 0; index < data_in_padding->len_data/16 ; ++index){
        array_xor(16, temp_out, data_in_padding->data + (index * 16), iv);      //明文与iv异或
        _aes128_encryption(key, cypher_out->data + index * 16, temp_out);       //进行块加密得到密文,同时密文是下次加密的iv
        memcpy(iv, cypher_out->data + index * 16, 16);                          //本次的密文是下次加密的iv
    }
    free(data_in_padding);
    return cypher_out;
}

2. 解密


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

aes-cbc模式加密_第2张图片

解密过程代码:

cypher_t* aes_cbc_decrypt(uint8_t* key, cypher_t* data_in)
{
    cypher_t* cypher_padding = block_padding(data_in);
    cypher_t* plain = (cypher_t*)malloc(data_in->len_data);
    plain->len_data = cypher_padding->len_data;
    uint8_t iv[16] = {0};
    memcpy(iv, IV, 16);
    uint8_t temp_out[16] = {0};
    for (uint8_t index = 0; index < cypher_padding->len_data/16 ; ++index){
        _aes128_decryption(key, temp_out, cypher_padding->data + (index*16));   //密文块解密
        array_xor(16, plain->data + (index*16), temp_out, iv);                  //与iv异或得到明文
        memcpy(iv, cypher_padding->data + (index*16), 16);                      //设置下次解密用到的iv
    }
    free(cypher_padding);
    return plain;
}

测试程序:

int main()
{
    uint8_t key[16] = {
        0x01, 0x02, 0x03, 0x04, 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff
    };
    uint8_t iv[16] = {
        0xa, 0xb, 0xc, 0xd, 0x1, 0x2, 0x3, 0x3, 0xa, 0xa, 0xa, 0xa, 0xf, 0xf, 0xf, 0xf
    };
    uint8_t* text = "hello aes_cbc encryption!";

    printf("密钥:");
    for (int i = 0; i < 16; ++i){
        if (i%4 == 0 && i != 0)
            printf(" ");
        if (i % 16 == 0 && i != 0)
            printf("\n");
        printf("%02x ", key[i]);
    }
    printf("\n");
    printf("明文:%s\n\n", text);

    set_iv(iv);
    //--------------------------aes cbc encrypt--------------------------------------
    cypher_t* plain = (cypher_t*)malloc(sizeof(uint8_t) + strlen(text));
    plain->len_data = strlen(text);
    memcpy(plain->data, text, plain->len_data);
    cypher_t* cypher = aes_cbc_encrypt(key, plain);
    puts("密文:");
    for (int i = 0; i < cypher->len_data; ++i){
        if (i%4 == 0 && i != 0)
            printf(" ");
        if (i % 16 == 0 && i != 0)
            printf("\n");
        printf("%02x ", cypher->data[i]);

    }
    printf("\n\n");
    free(plain);
    //--------------------------aes cbc decrypt--------------------------------------
    cypher_t* decrypted_plain = aes_cbc_decrypt(key, cypher);
    puts("解密之后:");
    for (int i = 0; i < decrypted_plain->len_data; ++i){
        if (i%4 == 0 && i != 0)
            printf(" ");
        if (i % 16 == 0 && i != 0)
            printf("\n");
        printf("%02x ", decrypted_plain->data[i]);
    }
    printf("\n\n");
    printf("解密之后的明文字符串输出:\n%s", decrypted_plain);
    printf("\n\n");
    free(decrypted_plain);
    return 0;
}

输出:

密钥: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!

你可能感兴趣的:(aes-cbc模式加密)