分组密码的模式AES-CBC模式流程解析附:应用代码实现

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

CBC模式的加解密

CBC模式中,首先将明文分组与前一个密文分组进行XOR运算,然后再进行加密。密文分组像链条一样相互连接在一起。

CBC模式的加密流程图

在这里插入图片描述

CBC模式的解密流程图

在这里插入图片描述

将一个分组的加密过程分离出来,对ECB模式和CBC模式进行比较,ECB模式只进行了加密,而CBC模式则在加密之前进行了一次XOR。

ECB模式与CBC模式的比较

在这里插入图片描述

初始化向量

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

注:在UDS 27hex服务中不同的初始化向量可以代表着不同的解锁等级。

应用代码:演示加密和解密过程。

/**
 * @file mainCBC.c
 * @author jimu (minijimu@foxmail.com)
 * @brief 
 * @version 0.1
 * @date 2024-09-02
 * 
 * @addtogroup 《图解密技术-第3版》
 * @copyright Copyright (c) 2024
 * 
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "aes.h"

// 假设我们有一个密钥和一个初始化向量(IV)
uint8_t key[AES_KEYLEN] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10};
uint8_t iv[AES_BLOCKLEN] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10};

// 加密函数
void encrypt(uint8_t *plaintext, uint8_t *ciphertext, size_t length)
{
    uint8_t *padded_text = (uint8_t *)malloc(length);
    memset(padded_text, 0, length);
    memcpy(padded_text, plaintext, length);
    AES_ctx ctx;
    AES_init_ctx_iv(&ctx, key, iv);
    if (length % AES_BLOCKLEN != 0)
    {
        printf("Error: Plaintext length must be a multiple of AES block size.\n");
        exit(1);
    }
    AES_CBC_encrypt_buffer(&ctx, padded_text, length);
    memcpy(ciphertext, padded_text, length);
    free(padded_text);
}

// 解密函数
void decrypt(uint8_t *ciphertext, uint8_t *decryptedtext, size_t length)
{
    AES_ctx ctx;
    AES_init_ctx_iv(&ctx, key, iv);
    if (length % AES_BLOCKLEN != 0)
    {
        printf("Error: Ciphertext length must be a multiple of AES block size.\n");
        exit(1);
    }
    AES_CBC_decrypt_buffer(&ctx, ciphertext, length);
    memcpy(decryptedtext, ciphertext, length);
}

int main()
{
    // 假设我们有一个明文消息
    const uint8_t plaintext[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00};
    size_t plaintext_len = sizeof(plaintext);

    // 虽然plaintext_len 是 AES_BLOCKLEN 的倍数,但是在加密和解密之前,我们需要确保 plaintext_len 是 AES_BLOCKLEN 的倍数。
    // 当前可认为是无填充模式。
    if (plaintext_len % AES_BLOCKLEN != 0)
    {
        plaintext_len = (plaintext_len / AES_BLOCKLEN + 1) * AES_BLOCKLEN;
    }

    // 为密文和明文缓冲区分配内存
    uint8_t *ciphertext = (uint8_t *)malloc(plaintext_len);
    uint8_t *decryptedtext = (uint8_t *)malloc(plaintext_len);

    printf("IV: ");
    for (size_t i = 0; i < AES_BLOCKLEN; i++)
    {
        printf("%02x", iv[i]);
    }
    printf("\n");
    printf("plaintext: ");
    for (size_t i = 0; i < sizeof(plaintext); i++)
    {
        printf("%02x", plaintext[i]);
    }
    printf("\n");
    // 加密
    encrypt((uint8_t *)plaintext, ciphertext, plaintext_len);

    // 打印密文
    printf("Ciphertext text:");
    for (size_t i = 0; i < plaintext_len; i++)
    {
        printf("%02x", ciphertext[i]);
    }
    printf("\n");

    // 解密
    decrypt(ciphertext, decryptedtext, plaintext_len);

    // 打印解密后的明文
    // printf("Decrypted text: %s\n", decryptedtext);
    printf("Decrypted text: ");
    for (size_t i = 0; i < plaintext_len; i++)
    {
        printf("%02x", decryptedtext[i]);
    }
    printf("\n");

    // 使用 memcmp 比较原始明文和解密后的文本
    if (memcmp(plaintext, decryptedtext, plaintext_len) == 0)
    {
        printf("Decryption successful!\n");
    }
    else
    {
        printf("Decryption failed!\n");
    }

    // 释放内存
    free(ciphertext);
    free(decryptedtext);
    getchar();
    return 0;
}

  • 对比代码加密和工具加密的结果

对比代码加密和工具加密的结果

代码简述

  1. 定义明文 plaintext 和其长度 plaintext_len
  2. 确保 plaintext_len 是 AES 块大小的倍数。
  3. 分配内存用于存储密文和解密后的明文。
  4. 打印初始化向量(IV)和明文。
  5. 调用 encrypt 函数加密明文。
  6. 打印密文。
  7. 调用 decrypt 函数解密密文。
  8. 打印解密后的明文。
  9. 比较原始明文和解密后的明文,确认解密成功。
  10. 释放内存。

CBC模式应用场景

  • 文件加密 :CBC 模式适合于加密静态文件,如备份文件或存储在硬盘上的数据。
  • 通信加密 :在网络通信中,CBC 模式可用于加密数据包,尤其是在需要确保数据块间相关性的场景下。
  • 数据库加密 :在数据库中存储敏感信息时,可以使用 CBC 模式来加密记录或字段。

实际应用注意事项

  • IV 的管理 :IV 应该是随机的,并且对于每个加密操作都是唯一的。IV 需要与密文一起存储或传输,以便解密时使用。
  • 填充机制 :选择合适的填充机制,并确保解密时正确去除填充。
  • 完整性检查 :单独使用 CBC 模式无法提供数据完整性验证。通常需要结合 MAC(Message Authentication Code)或数字签名来确保数据的完整性和真实性。
    并且对于每个加密操作都是唯一的。IV 需要与密文一起存储或传输,以便解密时使用。
  • 填充机制 :选择合适的填充机制,并确保解密时正确去除填充。
  • 完整性检查 :单独使用 CBC 模式无法提供数据完整性验证。通常需要结合 MAC(Message Authentication Code)或数字签名来确保数据的完整性和真实性。
  • 15
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值