C++实现CBC模式加密

前面写了ECB模式加密:ECB加密
很好奇CBC模式加密是如何实现的。
CBC模式的工作原理:
1.初始化向量:CBC模式需要有一个初始化向量IV,它的大小与块大小相同。IV通常是随机生成。它与第一个明文块一起使用,确保相同的明文在不同的加密过程中生成不同的密文

2.加密:第一个明文块与IV异或,结果通过加密算法加密(比如AES),生成第一个密文块。接下来第一个密文块再与第二个明文块进行异或,结果再进行加密生成第二个密文块。不断重复,直到结束。

3.解密:第一个密文块通过解密算法,得到一个中间结果。将中间结果与IV进行异或运算,恢复第一个明文块。接着对第二个密文块进行解密,并于第一个密文块进行异或,恢复第二个明文块,不断重复,直到完全解密。

通过以上过程发现,CBC相较于ECB安全性增强,每个密文块,不仅依赖于自身,还依赖于前一个密文块。缺点也是显而易见的,就是无法并行加密,加密过程和解密过程是按顺序进行的。

C++实现方式:

#include <openssl/evp.h>//支持各种加密算法的接口 
#include <openssl/rand.h>//用它生成密钥和IV 
#include <cstring> 
#include <iostream>

const int AES_KEY_LENGTH = 256;  // 密钥长度256比特 
const int AES_BLOCK_SIZE = 16;   // AES 每个块16比特 

void handleErrors() {
    std::cerr << "发生错误!\n";
    exit(1);
}//如果发生错误,调用该函数提示 

// AES CBC模式加密
int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
            unsigned char *iv, unsigned char *ciphertext) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();//进行加密 
    if (!ctx) handleErrors();//加密失败给出错误提示 

    if (EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv) != 1)//首次加密,使用初始化向量IV 
        handleErrors();//初始化失败,给出错误提示 

    int len;
    int ciphertext_len;//密文总长度 

    if (EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len) != 1)//接下来使用前一次的密文加密 
        handleErrors();
    ciphertext_len = len;//记录生成密文的总长度 

    if (EVP_EncryptFinal_ex(ctx, ciphertext + len, &len) != 1)
        handleErrors();//处理剩余的明文,填充成一个块,继续加密 
    ciphertext_len += len;//记录总长度 

    EVP_CIPHER_CTX_free(ctx);
    return ciphertext_len;//返回最终长度! 
}

// AES CBC模式解密
int decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
            unsigned char *iv, unsigned char *plaintext) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    if (!ctx) handleErrors();

    if (EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv) != 1)
        handleErrors();//首次解密,使用iv 

    int len;
    int plaintext_len;

    if (EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len) != 1)
        handleErrors();//接下来只需要用上一次的密文进行解密 
    plaintext_len = len;//记录明文总长度 

    if (EVP_DecryptFinal_ex(ctx, plaintext + len, &len) != 1)
        handleErrors();
    plaintext_len += len;

    EVP_CIPHER_CTX_free(ctx);
    return plaintext_len;
}

int main() {
    // 测试数据
    unsigned char key[AES_KEY_LENGTH / 8];
    unsigned char iv[AES_BLOCK_SIZE];
    
    // 随机生成密钥和IV
    if (!RAND_bytes(key, sizeof(key)) || !RAND_bytes(iv, sizeof(iv))) {
        std::cerr << "Error generating key/iv\n";
        return 1;
    }

    // 明文
    unsigned char plaintext[] = "HELLO,WORLD!";
    unsigned char ciphertext[128];
    unsigned char decryptedtext[128];
    std::cout << "\n原始明文:\n" << plaintext << std::endl;
     

    // 加密
    int ciphertext_len = encrypt(plaintext, strlen((char *)plaintext), key, iv, ciphertext);

    // 解密
    int decryptedtext_len = decrypt(ciphertext, ciphertext_len, key, iv, decryptedtext);
    decryptedtext[decryptedtext_len] = '\0';  // 添加字符串结束符

    // 输出结果
    std::cout << "加密后的密文:\n";
    for (int i = 0; i < ciphertext_len; i++) {
        std::cout << std::hex << (int)ciphertext[i];
    }
    std::cout << "\n解密后的明文:\n" << decryptedtext << std::endl;

    return 0;
}

最后的运行结果:
在这里插入图片描述

DES算法是一种对称加密算法,CBC模式是其常用的加密模式之一。在C语言中可以通过编写程序来实现DES算法和CBC模式的界面。 首先,需要引入DES算法和CBC模式所需的库文件。常用的库文件包括openssl/des.h和openssl/rand.h,可以通过在程序中包含相应的头文件来引入这些库文件。 其次,需要定义相关的变量和函数来实现DES算法和CBC模式的功能。常见的变量包括密钥、明文、密文、IV(初始化向量)等。常见的函数包括加密函数、解密函数、生成随机密钥函数等。 接下来,可以编写主函数来实现用户和程序的交互界面。可以通过命令行参数传递相关的参数,比如密钥、明文、加密或解密的选项等。用户可以通过命令行输入相应的参数来调用函数进行加密或解密操作。 程序运行时,可以先根据用户输入的参数生成随机密钥(如果用户没有指定密钥),然后调用相应的函数进行加密或解密操作。加密操作包括分组加密、生成密文和输出密文等步骤,解密操作包括分组解密、生成明文和输出明文等步骤。 最后,程序可以根据用户的选择输出加密或解密结果,并通过界面展示给用户。 总之,通过在C语言中编写适当的代码,我们可以实现DES算法和CBC模式的界面,使用户能够方便地进行加密和解密操作。这样的界面可以提供更加友好的用户体验,同时也可以加强对DES算法和CBC模式的理解和应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旺旺的碎冰冰~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值