当前位置: 首页 > article >正文

【C语言】使用 OpenSSL 进行 AES CBC 加密与解密

使用 OpenSSL 进行 AES CBC 加密与解密

在这篇文章中,我们将使用 OpenSSL 库实现 AES CBC 模式的加密和解密功能。AES(高级加密标准)是一种对称加密算法,广泛应用于数据保护。本示例展示了如何使用 PKCS#7 填充标准来处理明文的长度,以及如何确保在加密和解密过程中正确管理密钥和初始化向量(IV)。

代码实现

下面是实现 AES CBC 加密与解密的完整代码:

#include <stdio.h>  
#include <string.h>  
#include <openssl/aes.h>  
#include <openssl/rand.h>  

// PKCS#7 去除填充的函数
int pkcs7_unpad(unsigned char *data, int len) {  
    int padding = data[len - 1];  
    if (padding < 1 || padding > AES_BLOCK_SIZE) {
        return -2;  // 错误的填充
    }
    for (int i = len - padding; i < len; i++) {
        if (data[i] != padding) return -1;  // 填充不正确
    }
    return len - padding; 
}

// PKCS#7 填充函数
void pkcs7_pad(unsigned char *plaintext, int plaintext_len, int block_size) {  
    int padding = block_size - (plaintext_len % block_size);  
    memset(plaintext + plaintext_len, padding, padding);
}

// AES CBC 解密函数
int aes_cbc_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext) {
    AES_KEY dec_key;  
    if (AES_set_decrypt_key(key, 256, &dec_key) < 0) {
        return -2;  // 设置解密密钥失败
    }

    int block_size = AES_BLOCK_SIZE;  
    if (ciphertext_len % block_size != 0) {
        return -3;  // 密文长度不是块大小的倍数
    }

    // 进行解密
    AES_cbc_encrypt(ciphertext, plaintext, ciphertext_len, &dec_key, iv, AES_DECRYPT);  
    int plaintext_len = pkcs7_unpad(plaintext, ciphertext_len);  
    if (plaintext_len < 0) {
        return plaintext_len;  // 填充去除失败
    }

    return plaintext_len;  
} 

// AES CBC 加密函数  
int aes_cbc_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext) {  
    AES_KEY enc_key;  
    AES_set_encrypt_key(key, 256, &enc_key);  

    int block_size = AES_BLOCK_SIZE;  
    int padding = block_size - (plaintext_len % block_size);  
    int ciphertext_len = plaintext_len + padding;  

    unsigned char plaintext2[ciphertext_len];
    memcpy(plaintext2, plaintext, plaintext_len);
    pkcs7_pad(plaintext2, plaintext_len, block_size);  

    AES_cbc_encrypt(plaintext2, ciphertext, ciphertext_len, &enc_key, iv, AES_ENCRYPT);  

    return ciphertext_len;  
}

int main() {
    // 假设的密钥和IV  
    unsigned char key[AES_BLOCK_SIZE * 2] = "your-256-bit-key-here-xxxxxxxxxx";  
    unsigned char iv[AES_BLOCK_SIZE] = "your-iv-here-xxx";  
    
    // 明文  
    unsigned char plaintext[] = "Hello,World";  
    int plaintext_len = strlen((char *)plaintext);  

    unsigned char *ciphertext_buffer = malloc(plaintext_len + AES_BLOCK_SIZE);  
    if (ciphertext_buffer == NULL) {  
        return 1;  
    }  
    
    int ret_len = aes_cbc_encrypt(plaintext, plaintext_len, key, iv, ciphertext_buffer);
    
    unsigned char iv2[AES_BLOCK_SIZE] = "your-iv-here-xxx";  
    unsigned char *plaintext_buffer2 = malloc(plaintext_len + AES_BLOCK_SIZE);  
    int code = aes_cbc_decrypt(ciphertext_buffer, ret_len, key, iv2, plaintext_buffer2);
    
    printf("Decrypted: %.*s\n", code, plaintext_buffer2);

    free(ciphertext_buffer);
    free(plaintext_buffer2);
    return 0;
}

代码分析

1. 填充与去填充

我们使用 PKCS#7 填充标准来处理明文长度。这种填充方式确保了明文的长度是块大小的倍数,便于后续的加密操作。

2. AES 加密与解密

aes_cbc_encrypt 函数负责加密明文,而 aes_cbc_decrypt 函数则负责解密密文。在这两个函数中,我们都使用了相同的密钥和初始化向量。

3. 主函数

main 函数中,我们定义了明文、密钥和 IV。我们调用加密和解密函数,并打印出解密后的结果。

总结

本文展示了如何使用 OpenSSL 实现 AES CBC 模式的加密与解密。通过合理的填充和去填充机制,我们确保了数据的完整性与安全性。在实际应用中,请确保密钥和 IV 的安全性,以防止潜在的安全风险。

补充

环境:安装OpenSSL

1. Ubuntu/Debian

打开终端,运行以下命令:

sudo apt update
sudo apt install openssl libssl-dev
2. CentOS

对于 CentOS ,可以使用以下命令:

sudo yum install openssl openssl-devel

编译

gcc -o main main.c -lcrypto

http://www.kler.cn/a/318800.html

相关文章:

  • Python提取PDF和DOCX中的文本、图片和表格
  • 区块链技术在慈善捐赠中的应用
  • [代码随想录Day10打卡] 理论基础 232.用栈实现队列 225. 用队列实现栈 20. 有效的括号 1047. 删除字符串中的所有相邻重复项
  • jmeter常用配置元件介绍总结之定时器
  • 《MYSQL45讲》kill不掉的线程
  • 10款翻译工具实践体验感受与解析!!!!!
  • linux静态路由表
  • Nginx静态资源优化、压缩、缓存处理
  • 像百度谷歌这种网站会被DDoS吗
  • 全球商旅,提升人效,就选用友BIP超级版!
  • 【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
  • 基于springboot在线点餐系统
  • 2024源代码加密软件TOP10排行榜丨保护企业源代码安全不泄露
  • [数据结构与算法·C++版] 笔记 1.2 什么是数据结构
  • docker快速部署zabbix
  • 快递智能地址解析API接口代码
  • 支持K歌音箱方案应用的高性能 32 位蓝牙音频应用处理器-BP1048B2
  • 【解决方案】git错误:对象文件为空 error: object file
  • 考研日语 - 高频核心 2200 词(五)
  • 【算法】模拟:(leetcode)495.提莫攻击(easy)
  • linux服务器自动同步数据库
  • vue3腾讯云实时音视频通话 ui集成方案TUIcallkit
  • 富格林:可信交易筹划在线曝光
  • Python 解析 html
  • 股指期货理论价格计算公式是什么?
  • 【论文】FunAudioLLM:一个旨在增强人类与大型语言模型(LLMs)之间自然语音交互的模型家族