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

使用C++的OpenSSL 库实现 AES 加密和解密文件

        如果C++不知道做什么项目,可以编写一个文件加密和解密工具,支持诸如 AES 和 RSA 等常见的加密算法。这样的项目可以帮助学习和理解现代加密技术,并为日常文件保护提供便利。以下是一个基本的设计思路和实现步骤:

1. 设计思路

a. 功能需求
  1. 文件加密:支持对文件进行加密。
  2. 文件解密:支持对加密文件进行解密。
  3. 加密算法选择:支持选择不同的加密算法,如 AES、RSA 等。
  4. 密钥管理:生成和管理加密密钥。
  5. 文件操作:能够读取和写入文件。
b. 技术选型
  1. 加密库:使用 OpenSSL 或 Crypto++ 等成熟的加密库来实现加密和解密功能。
  2. 文件 I/O:使用 C++ 标准库中的文件操作功能来读取和写入文件。
  3. 命令行界面:使用简单的命令行界面(CLI)来接收用户输入和显示结果。

2. 实现步骤

a. 环境准备
  • 安装 OpenSSL 或 Crypto++ 库。
  • 创建一个新的 C++ 项目。
b. 使用 OpenSSL 实现 AES 加密和解密

OpenSSL 提供了丰富的加密功能,以下是如何实现 AES 加密和解密的示例。

#include <openssl/evp.h>
#include <openssl/rand.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <iostream>
#include <string>
// 以上是下面加密算法和解密算法要用到的头文件
参数:
  • const std::string& file:要加密的文件的路径。
  • const std::string& algorithm:使用的加密算法(目前仅支持 “aes”)。

生成 AES-256 加密所需的 32 字节密钥(key)和 16 字节初始化向量(IV),使用 RAND_bytes 函数生成随机字节。同时将生成的密钥和 IV 写入一个名为 file.key 的文件中,以便解密时使用。 


void encrypt_file(const std::string& file, const std::string& algorithm) {
    // 也就是说当前仅支持AES加密算法
    if (algorithm != "aes") {
        std::cerr << "不支持该加密算法: " << algorithm << std::endl;
        return;
    }

    const unsigned int key_len = 32; // AES-256 key length
    const unsigned int iv_len = 16;  // IV length
    unsigned char key[key_len], iv[iv_len];

    // 生成密钥和 IV
    RAND_bytes(key, key_len);
    RAND_bytes(iv, iv_len);

    // 保存密钥和 IV
    std::ofstream key_file(file + ".key", std::ios::binary);
    key_file.write((char*)key, key_len);
    key_file.write((char*)iv, iv_len);
    key_file.close();

    // 打开输入文件
    std::ifstream infile(file, std::ios::binary);
    if (!infile) {
        std::cerr << "无法打开文件: " << file << std::endl;
        return;
    }

    // 打开输出文件
    std::ofstream outfile(file + ".enc", std::ios::binary);
    if (!outfile) {
        std::cerr << "无法新建输出文件." << std::endl;
        return;
    }

    // 初始化加密上下文
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);

    // 加密文件
    unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
    int inlen, outlen;
    while (infile.good()) {
        infile.read((char*)inbuf, sizeof(inbuf));
        inlen = infile.gcount();
        if (inlen > 0) {
            EVP_EncryptUpdate(ctx, outbuf, &outlen, inbuf, inlen);
            outfile.write((char*)outbuf, outlen);
        }
    }

    // 结束加密
    EVP_EncryptFinal_ex(ctx, outbuf, &outlen);
    outfile.write((char*)outbuf, outlen);

    // 清理
    EVP_CIPHER_CTX_free(ctx);
    infile.close();
    outfile.close();

    std::cout << "文件加密成功: " << file + ".enc" << std::endl;
}


void decrypt_file(const std::string& file, const std::string& algorithm) {
    if (algorithm != "aes") {
        std::cerr << "不支持该算法: " << algorithm << std::endl;
        return;
    }

    const unsigned int key_len = 32; // AES-256 key length
    const unsigned int iv_len = 16;  // IV length
    unsigned char key[key_len], iv[iv_len];

    // 读取密钥和 IV
    std::ifstream key_file(file + ".key", std::ios::binary);
    if (!key_file) {
        std::cerr << "无法打开密钥文件." << std::endl;
        return;
    }
    key_file.read((char*)key, key_len);
    key_file.read((char*)iv, iv_len);
    key_file.close();

    // 打开输入文件
    std::ifstream infile(file, std::ios::binary);
    if (!infile) {
        std::cerr << "无法打开输入文件: " << file << std::endl;
        return;
    }

    // 打开输出文件
    std::ofstream outfile(file + ".dec", std::ios::binary);
    if (!outfile) {
        std::cerr << "无法创建输出文件." << std::endl;
        return;
    }

    // 初始化解密上下文
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);

    // 解密文件
    unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
    int inlen, outlen;
    while (infile.good()) {
        infile.read((char*)inbuf, sizeof(inbuf));
        inlen = infile.gcount();
        if (inlen > 0) {
            EVP_DecryptUpdate(ctx, outbuf, &outlen, inbuf, inlen);
            outfile.write((char*)outbuf, outlen);
        }
    }

    // 结束解密
    EVP_DecryptFinal_ex(ctx, outbuf, &outlen);
    outfile.write((char*)outbuf, outlen);

    // 清理
    EVP_CIPHER_CTX_free(ctx);
    infile.close();
    outfile.close();

    std::cout << "文件解密成功: " << file + ".dec" << std::endl;
}
 c. 命令行界面设计

设计一个简单的命令行界面,接收用户的输入并执行相应的操作。


void show_help() {
    std::cout << "用法: encryptor [options]" << std::endl;
    std::cout << "参数选项:" << std::endl;
    std::cout << "  -e <file> <algorithm>  加密文件" << std::endl;
    std::cout << "  -d <file> <algorithm>  解密文件" << std::endl;
    std::cout << "  -h                     帮助信息" << std::endl;
}

int main(int argc, char* argv[]) {
    if (argc < 2) {
        show_help();
        return 1;
    }

    std::string option = argv[1];
    if (option == "-h") {
        show_help();
    } else if (option == "-e" && argc == 4) {
        std::string file = argv[2];
        std::string algorithm = argv[3];
        // 调用加密函数
        encrypt_file(file, algorithm);
    } else if (option == "-d" && argc == 4) {
        std::string file = argv[2];
        std::string algorithm = argv[3];
        // 调用解密函数
        decrypt_file(file, algorithm);
    } else {
        std::cerr << "无效参数" << std::endl;
        show_help();
        return 1;
    }

    return 0;
}

3. 运行和测试

编译并运行你的程序,确保能够正确加密和解密文件。可以通过以下命令进行测试:encryptor是你生成的可执行文件名称

# 加密文件
./encryptor -e input.txt aes

# 解密文件
./encryptor -d input.txt.enc aes

4. 扩展功能

你可以进一步扩展这个工具的功能,例如:

  • 支持多种加密算法:如 RSA、DES 等。
  • 用户输入密钥:允许用户输入或选择密钥。
  • 图形用户界面:使用 Qt 或 wxWidgets 等库来创建一个图形界面。

总结

通过这个项目,你不仅可以学习到如何使用 OpenSSL 或 Crypto++ 等加密库,还能深入理解现代加密技术的工作原理,希望这个设计思路和实现步骤能对你有帮助。


http://www.kler.cn/news/332751.html

相关文章:

  • 【2022工业3D异常检测文献】BTF: 结合手工制作的3D描述和颜色特征的异常检测方法
  • 大数据实时数仓Hologres(四):基于Flink+Hologres搭建实时数仓
  • SpringBoot的数据访问
  • TCP Analysis Flags 之 TCP ZeroWindowProbe
  • 忘记 MySQL 密码怎么办:破解 root 账户密码
  • 【JavaEE】http/https 超级详解
  • 认知杂谈97《兼听则明,偏听则暗》
  • 考研日语 - 高频核心 2200 词(八)
  • 【py】python实现矩阵的加、减、点乘、乘法
  • 多线程-初阶(1)
  • QT系统学习篇(1)
  • 算法笔记(九)——栈
  • 在springboot项目中实现一个定时任务执行的功能
  • 基于Springboot+Vue的小区停车场管理系统登录(含源码数据库)
  • wsl2 ubuntu 桥接以太网卡
  • git维护【.gitignore文件】
  • Microsoft 更新 Copilot AI,未來將能使用語音並看到你瀏覽的網頁
  • SpringCloud学习记录|day2
  • 手机实时提取SIM卡打电话的信令声音-(题外、插播一条广告)
  • Ubuntu安装Hadoop3.4