首页 > 其他分享 >分组密码的模式AES-CBC模式流程解析附:应用代码实现

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

时间:2024-09-02 21:54:13浏览次数:10  
标签:CBC AES 加密 plaintext 模式 len printf

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 ([email protected])
 * @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)或数字签名来确保数据的完整性和真实性。

标签:CBC,AES,加密,plaintext,模式,len,printf
From: https://blog.csdn.net/m0_48119914/article/details/141831174

相关文章

  • GoF 代理模式
    代理模式的理解代理模式,就是自己做不了,需要别人来代理,代替自己来完成。最终这个行为还是要发生,只不过不是由自己来完成,而是由别人代理完成,只是对于客户其他人来说感受不到代理模式的作用:当一个对象需要受到保护时,可以考虑使用代理模式去完成某个行为。需要给某个对象的功能......
  • C语言:大小端模式、判断大小端、大小端转换
    目录1.什么是大端和小端2.为什么会存在大小端的问题3.判断主机字节序(主机大小端)3.1使用联合体(union)3.2使用指针3.3强制转为char类型法4.大小端转换1.什么是大端和小端对于一个存储空间大于1个字节的数据,在内存中有两种存储模式,大端模式(big-end......
  • 设计模式-工厂模式设计与详解
    一、工厂模式概述工厂模式(FactoryPattern)是一种常用的创建型设计模式,其核心目的是实现创建对象的接口和具体的实例化分离,通过建立一个工厂类,对实现了同一接口的一些类进行实例的创建,以增加系统的灵活性和可维护性。当需要大量创建一个类的实例的时候,可以使用工厂模式,即从原生的使......
  • 设计模式-工厂方法模式
    ......
  • 每日一题08:说一下Spring AOP动态代理模式
    回答1:SpringAOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。SpringAOP中的动态代理主要有两种方式,JDK动态代理和CGL......
  • 设计模式之备忘录模式
    备忘录模式(MementoPattern)官方的定义是这样的:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。它是面向对象的23种设计模式中的一种,属于行为模式的范围。直白点说就是:我们可以在不暴露更多字段的前提下,直接将......
  • 文心快码前端工程师观点分享:人机协同新模式的探索之路(一)
    ......
  • 摄影曝光:曝光模式认知
    写在前面学习整理《摄影曝光:拍出好照片的49个关键技法》读书笔记博文内容涉及曝光模式简单认知适合小白认知理解不足小伙伴帮忙指正......
  • 文心快码前端工程师观点分享:人机协同新模式的探索之路(一)
    进入文心快码BaiduComate官网,体验智能编码之旅,还有超多福利!本系列视频来自百度工程效能部的前端研发经理杨经纬,她在由开源中国主办的“AI编程革新研发效能”OSC源创会·杭州站·105期线下沙龙活动上,从一款文心快码(BaiduComate)前端工程师的角度,分享了关于智能研发工具本身的研发......
  • 问题-解决方案对-《分析模式》漫谈24
    DDD领域驱动设计批评文集做强化自测题获得“软件方法建模师”称号《软件方法》各章合集“AnalysisPatterns”的第一章有这么一句:Itisanimportantformbecauseitsupportsthedefinitionofapatternas"asolutiontoaproblemincontext," adefinitionthat......