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

用 OpenSSL 库实现 3DES(三重DES)加密

用 OpenSSL 库实现 3DES(三重DES)加密操作。以下是代码的详细解析:

1. 包含头文件和命名空间:

#include <iostream>
#include <openssl/evp.h>
#include <openssl/err.h>
  • #include : 引入 C++ 标准库,用于输入输出操作。
  • #include <openssl/evp.h>: 引入 OpenSSL 的 EVP (Envelope) API,这是 OpenSSL 提供的高级加解密接口。
  • #include <openssl/err.h>: 引入 OpenSSL 错误处理头文件,用于打印 OpenSSL 错误。

2. 定义 main 函数并初始化数据:

int main(int argc, char *argv[])
{const unsigned char data[] = "1234567812345678"; // 输入int data_size = sizeof(data) - 1;                // 计算数据长度,不包括'\0'cout << "data_size = " << data_size << endl;
  • data[]: 需要加密的输入数据(字符串 “1234567812345678”)。
  • data_size: 计算数据长度,这里使用 sizeof(data) - 1,因为 sizeof(data) 会包括末尾的 ‘\0’ 字符,因此需要减去 1。

3. 定义加密参数:

unsigned char out[1024] = {0};                      // 输出
unsigned char key[] = "123456789012345678901234"; // 24 字节的密钥(3DES)
unsigned char iv[8] = {0};                          // 8 字节的初始化向量(IV)
  • out[]: 用来存储加密后的输出数据。
  • key[]: 3DES 使用的密钥,3DES 算法需要 24 字节的密钥。此处密钥被设置为 - “123456789012345678901234”,总长度为 24 字节。
  • iv[]: 初始化向量(IV),用于加密过程中的随机化,长度为 8 字节。

4. 选择加密算法和打印加密参数:

// 三重DES 3DES 算法
auto cipher = EVP_des_ede3_cbc();
// 获取算法的分组大小
int block_size = EVP_CIPHER_block_size(cipher);
int key_size = EVP_CIPHER_key_length(cipher);
int iv_size = EVP_CIPHER_iv_length(cipher);
cout << "block_size = " << block_size << endl;
cout << "key_size = " << key_size << endl;
cout << "iv_size = " << iv_size << endl;
  • EVP_des_ede3_cbc(): 使用 OpenSSL 的 EVP API 来选择三重 DES(3DES)加密算法,这里使用的是 3DES 的 CBC 模式(密码分组链接模式)。
  • EVP_CIPHER_block_size(cipher): 获取加密算法的分组大小(即块大小)。对于 3DES,块大小为 8 字节。
  • EVP_CIPHER_key_length(cipher): 获取密钥的长度。对于 3DES,密钥长度为 24 字节。
  • EVP_CIPHER_iv_length(cipher): 获取 IV(初始化向量)的长度。对于 3DES,IV 长度为 8 字节。

5. 初始化加解密上下文并开始加密:

// 加解密上下文
auto ctx = EVP_CIPHER_CTX_new();
// 加密算法初始化int re = EVP_CipherInit_ex(ctx, cipher, nullptr, key, iv, 1); // 1表示加密
if (!re)
{ERR_print_errors_fp(stderr);getchar();return -1;
}
cout << "EVP_CipherInit success!" << endl;
  • EVP_CIPHER_CTX_new(): 创建一个新的加解密上下文,用于存储加解密的状态。
  • EVP_CipherInit_ex(ctx, cipher, nullptr, key, iv, 1): 初始化加解密上下文,传入所选择的加密算法、密钥、初始化向量和加密模式。这里的 1 表示加密模式(解密时应该传 0)。如果初始化失败,程序会打印错误信息并退出。

6. 设置填充方式:

 // 设置填充方式(默认是 PKCS7)EVP_CIPHER_CTX_set_padding(ctx, EVP_PADDING_PKCS7);
  • EVP_CIPHER_CTX_set_padding(ctx, EVP_PADDING_PKCS7): 设置加密过程中的填充方式。默认使用 PKCS7 填充方式,即使加密数据不是块大小的整数倍,也会进行填充,使其对齐到块大小。

7. 执行加密操作:

int out_size = 0;
EVP_CipherUpdate(ctx, out, &out_size, data, data_size);
cout << "EVP_CipherUpdate size: " << out_size << endl;
  • EVP_CipherUpdate(ctx, out, &out_size, data, data_size): 进行加密操作,将输入数据 data 加密后写入 out 中,out_size 存储实际加密后的字节数。

8. 处理最后的填充块:

  int padding_size = 0;EVP_CipherFinal_ex(ctx, out + out_size, &padding_size);cout << "padding_size = " << padding_size << endl;out_size += padding_size;
  • EVP_CipherFinal_ex(ctx, out + out_size, &padding_size): 获取加密结果的最后一块数据(如果有填充)。填充是为了保证加密数据大小是块大小的整数倍。
  • padding_size: 返回填充数据的大小。将其加到 out_size 中,得到总的加密数据大小。

9. 打印加密后的数据:

   cout << "Encrypted data: ";for (int i = 0; i < out_size; ++i){printf("%02x", out[i]); // 以十六进制打印每个字节}cout << endl;
  • 打印加密后的数据。由于输出的是字节数据,直接打印可能显示为乱码,因此使用 printf(“%02x”, out[i]) 以十六进制格式打印每个字节。

10. 释放上下文并结束程序:

   // 释放上下文EVP_CIPHER_CTX_free(ctx);getchar();return 0;
}
  • EVP_CIPHER_CTX_free(ctx): 释放加解密上下文,以避免内存泄漏。
  • getchar(): 用于暂停程序,等待用户输入,便于查看加密结果。

总结:

该程序使用 OpenSSL 库的 EVP API 对数据进行 3DES 加密,使用 CBC 模式。通过初始化密钥、初始化向量(IV)和加密上下文来执行加密,并处理填充。最后,程序以十六进制格式打印加密后的数据。

完整代码

#include <iostream>
#include <openssl/evp.h>
#include <openssl/err.h>// _CRT_SECURE_NO_WARNINGS
// #include <openssl/applink.c>
using namespace std;int main(int argc, char *argv[])
{const unsigned char data[] = "1234567812345678"; // 输入int data_size = sizeof(data) - 1;                // 计算数据长度,不包括'\0'cout << "data_size = " << data_size << endl;unsigned char out[1024] = {0};                    // 输出unsigned char key[] = "123456789012345678901234"; // 24 字节的密钥(3DES)unsigned char iv[8] = {0};                        // 8 字节的初始化向量(IV)// 三重DES 3DES 算法auto cipher = EVP_des_ede3_cbc();// 获取算法的分组大小int block_size = EVP_CIPHER_block_size(cipher);int key_size = EVP_CIPHER_key_length(cipher);int iv_size = EVP_CIPHER_iv_length(cipher);cout << "block_size = " << block_size << endl;cout << "key_size = " << key_size << endl;cout << "iv_size = " << iv_size << endl;// 加解密上下文auto ctx = EVP_CIPHER_CTX_new();// 加密算法初始化int re = EVP_CipherInit_ex(ctx, cipher, nullptr, key, iv, 1); // 1表示加密if (!re){ERR_print_errors_fp(stderr);getchar();return -1;}cout << "EVP_CipherInit success!" << endl;// 设置填充方式(默认是 PKCS7)EVP_CIPHER_CTX_set_padding(ctx, EVP_PADDING_PKCS7);int out_size = 0;// 只处理分组大小得到数据, 如果取消自动填充,多余数据丢弃EVP_CipherUpdate(ctx, out, &out_size, data, data_size);cout << "EVP_CipherUpdate size: " << out_size << endl;// 取出最后一块数据(需要填充的),或者是 padding 补充的数据int padding_size = 0;EVP_CipherFinal_ex(ctx, out + out_size, &padding_size);cout << "padding_size = " << padding_size << endl;out_size += padding_size;// 打印加密后的数据cout << "Encrypted data: ";for (int i = 0; i < out_size; ++i){printf("%02x", out[i]); // 以十六进制打印每个字节}cout << endl;// 释放上下文EVP_CIPHER_CTX_free(ctx);getchar();return 0;
}

相关文章:

  • SSL错误无法建立安全连接
  • 三数之和-力扣
  • Koji构建系统宏定义注入与Tag体系解析
  • Bright Data网页抓取工具实战:BOSS直聘爬虫 + PandasAI分析洞察前端岗位市场趋势
  • 西安java面经1
  • Node.js Conf 配置库要点分析 和 使用注意事项
  • 云原生安全实践:CI/CD流水线集成DAST工具
  • 【Lua热更新知识】学习一 Lua语法学习
  • Delphi 获取 XP系统 mac地址
  • 四大LLM 微调开源工具包深度解析
  • 算法第13天|继续学习二叉树:平衡二叉树(递归)、二叉树所有路径(递归)、左叶子之和(递归)
  • mysql如何快速生成测试大数据库
  • Rust 学习笔记:关于 Future trait 和 Async 语法的练习题
  • 项目练习:使用mybatis的foreach标签,实现union all的拼接语句
  • 【Linux shell】条件判断和流程控制
  • 第十四章 Linux实操篇——进程管理(重点)
  • 网络原理8 - HTTP协议1
  • AI Agent 核心策略解析:Function Calling 与 ReAct 的设计哲学与应用实践
  • python打卡day51
  • 计算机视觉与深度学习 | 两种经典的低照度增强算法:多尺度Retinex(MSR)和自适应直方图均衡化(CLAHE)
  • 做好的网站怎么优化/app推广兼职是诈骗吗
  • 青岛网站开发公司/搜狗官网
  • 长沙最新死亡事件/seo零基础教学视频
  • 宁波做网站 主觉文化/深圳网页设计
  • 免费1级做爰片在线观看 历史网站/线上广告接单平台
  • 没有网站可以做cpa广告么/100大看免费行情的软件