用c++实现基于openssl的大文件的对称加密与解密
时间: 2023-12-22 14:02:32 浏览: 158
以下是使用 OpenSSL 库进行大文件对称加密和解密的 C++ 代码示例:
```c++
#include <iostream>
#include <fstream>
#include <string>
#include <openssl/aes.h>
#include <openssl/evp.h>
using namespace std;
// 加密函数
void encrypt_file(const char *in_filename, const char *out_filename, const unsigned char *key) {
// 打开输入文件和输出文件
ifstream in_file(in_filename, ios::binary);
ofstream out_file(out_filename, ios::binary);
// 初始化加密上下文
EVP_CIPHER_CTX *ctx;
ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, NULL);
// 定义缓冲区
unsigned char in_buf[AES_BLOCK_SIZE];
unsigned char out_buf[AES_BLOCK_SIZE + EVP_MAX_BLOCK_LENGTH];
int num_read = 0;
int num_written = 0;
int out_len = 0;
// 读取输入文件并进行加密
while (in_file.read((char*)in_buf, AES_BLOCK_SIZE)) {
EVP_EncryptUpdate(ctx, out_buf, &out_len, in_buf, AES_BLOCK_SIZE);
out_file.write((char*)out_buf, out_len);
num_read += AES_BLOCK_SIZE;
num_written += out_len;
}
// 处理最后一块数据
if (in_file.eof() && in_file.gcount() > 0) {
EVP_EncryptUpdate(ctx, out_buf, &out_len, in_buf, in_file.gcount());
out_file.write((char*)out_buf, out_len);
num_read += in_file.gcount();
num_written += out_len;
}
// 完成加密过程
EVP_EncryptFinal_ex(ctx, out_buf, &out_len);
out_file.write((char*)out_buf, out_len);
num_written += out_len;
// 清理加密上下文
EVP_CIPHER_CTX_free(ctx);
// 关闭文件
in_file.close();
out_file.close();
// 输出加密结果
cout << "Encrypted " << num_read << " bytes to " << num_written << " bytes." << endl;
}
// 解密函数
void decrypt_file(const char *in_filename, const char *out_filename, const unsigned char *key) {
// 打开输入文件和输出文件
ifstream in_file(in_filename, ios::binary);
ofstream out_file(out_filename, ios::binary);
// 初始化解密上下文
EVP_CIPHER_CTX *ctx;
ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, NULL);
// 定义缓冲区
unsigned char in_buf[AES_BLOCK_SIZE + EVP_MAX_BLOCK_LENGTH];
unsigned char out_buf[AES_BLOCK_SIZE];
int num_read = 0;
int num_written = 0;
int out_len = 0;
// 读取输入文件并进行解密
while (in_file.read((char*)in_buf, AES_BLOCK_SIZE + EVP_MAX_BLOCK_LENGTH)) {
EVP_DecryptUpdate(ctx, out_buf, &out_len, in_buf, AES_BLOCK_SIZE + in_file.gcount() - AES_BLOCK_SIZE);
out_file.write((char*)out_buf, out_len);
num_read += AES_BLOCK_SIZE + in_file.gcount() - AES_BLOCK_SIZE;
num_written += out_len;
}
// 完成解密过程
EVP_DecryptFinal_ex(ctx, out_buf, &out_len);
out_file.write((char*)out_buf, out_len);
num_written += out_len;
// 清理解密上下文
EVP_CIPHER_CTX_free(ctx);
// 关闭文件
in_file.close();
out_file.close();
// 输出解密结果
cout << "Decrypted " << num_read << " bytes to " << num_written << " bytes." << endl;
}
int main() {
// 定义密钥
unsigned char key[AES_BLOCK_SIZE];
memset(key, 0x00, AES_BLOCK_SIZE);
// 加密文件
encrypt_file("input.bin", "output.bin", key);
// 解密文件
decrypt_file("output.bin", "input.bin", key);
return 0;
}
```
在上面的代码中,我们使用了 `EVP_aes_256_cbc()` 算法进行加密和解密操作,这是一种常用的对称加密算法。我们还使用了 `EVP_CIPHER_CTX_new()` 和 `EVP_CIPHER_CTX_free()` 函数来初始化和清理加密和解密上下文,这是 OpenSSL 库提供的一种方便的方式。
值得注意的是,由于我们使用了流式的输入输出方式,所以该代码可以处理任意大小的文件。当然,如果你的文件非常大,可能需要分块处理以避免内存溢出问题。此外,为了简化代码,我们在示例中使用了一个固定的密钥,实际中应该使用更复杂的密钥管理方案。
阅读全文