记录一个视频加密解密--AES 进阶版 (EVP)

OpenSSL 是一个开源的软件库,提供了一组用于进行加密、解密、哈希和证书操作的函数和工具。其中,EVP(Envelope Cryptography API)是 OpenSSL 中的一个模块,用于处理对称加密和哈希算法。
EVP 提供了一个统一的接口,使得开发人员能够使用相同的代码处理不同的加密算法,而无需关心具体的算法细节。它支持对称加密算法(如 AES、DES、RC4)、哈希算法(如 MD5、SHA-1)以及其他一些密码学功能。

EVP 模块的主要特点和功能:

  1. 简化的编程接口:EVP 提供了一个高级的、简化的编程接口,使得开发人员可以使用相同的方式处理各种对称加密和哈希算法,无需直接操作底层算法细节。
  2. 支持多种加密算法:EVP 支持多种常见的对称加密算法,如 AES、DES、RC4 等,以及一些其他的算法。
  3. 支持多种哈希算法:EVP 支持多种常见的哈希算法,如 MD5、SHA-1、SHA-256 等,以及一些其他的算法。
  4. 提供安全的随机数生成:EVP 提供了安全的伪随机数生成函数,用于生成加密过程中所需的随机数,以增加安全性。
  5. 支持密码学功能:EVP 不仅提供了加密和哈希算法,还支持其他密码学功能,如数字签名、密钥派生、公钥加密等。

使用 EVP 模块可以极大地简化密码学操作的代码编写过程,并提高代码的可读性和可维护性。开发人员可以根据需要选择适当的算法和函数来实现加密、解密、哈希和其他密码学功能。同时,EVP 模块也遵循了密码学的最佳实践和标准,提供了可信赖的加密和哈希功能。

想要详细了解的可以单独去搜索相关资料,这里还是使用 EVP_aes_256_cbc 来加密。
EVP_aes_256_cbc 提供了一种安全且广泛使用的加密算法,适用于保护敏感数据的机密性

  1. 密钥长度:EVP_aes_256_cbc 使用 256 位的密钥长度,提供更高的安全性,使得破解密钥变得困难。
  2. 加密模式:EVP_aes_256_cbc 使用 CBC 模式,在加密数据块之前,先将明文分块,并将前一个密文块与当前明文块进行异或运算,以增强加密的随机性和安全性。
  3. 填充方式:EVP_aes_256_cbc 使用标准的填充方式(PKCS#5 或 PKCS#7),以确保待加密数据的长度是块长度的整数倍。
  4. 初始化向量(IV):CBC 模式需要一个初始化向量作为初始状态。开发人员需要自行生成一个安全的随机初始化向量,并在加密和解密时保持一致。
  5. 安全性:EVP_aes_256_cbc 是一个被广泛接受和使用的加密算法,提供了较高的安全强度。然而,为了确保最佳的安全性,开发人员还应采取其他安全措施,如正确处理密钥、随机数和不当使用情况等。

密钥问题: 在算法中真正使用的密钥长度和初始化密钥长度是根据算法来决定的。(也就是你传入的key或者iv长度可以是任意的,实际使用的数据取决于算法,不足会自动补上,超过会自动舍去

#include <iostream>
#include <openssl/aes.h>
#include <openssl/evp.h>


bool encryptFile(const std::string& inputFile, const std::string& outputFile, const std::string& key, const std::string& iv) {
	// 初始化 OpenSSL 的 EVP 库
	EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
	if (!ctx) {
		std::cout << "无法初始化 OpenSSL EVP 库" << std::endl;
		return false;
	}

	// 使用 AES-256-CBC 加密算法
	const EVP_CIPHER* cipher = EVP_aes_256_cbc();

	// 初始化加密上下文
	if (EVP_EncryptInit_ex(ctx, cipher, nullptr, (const unsigned char*)key.c_str(), (const unsigned char*)iv.c_str()) != 1) {
		std::cout << "无法初始化加密上下文" << std::endl;
		EVP_CIPHER_CTX_free(ctx);
		return false;
	}

	// 打开输入文件
	FILE* inFile = fopen(inputFile.c_str(), "rb");
	if (!inFile) {
		std::cout << "无法打开输入文件" << std::endl;
		EVP_CIPHER_CTX_free(ctx);
		return false;
	}

	// 创建输出文件
	FILE* outFile = fopen(outputFile.c_str(), "wb");
	if (!outFile) {
		std::cout << "无法创建输出文件" << std::endl;
		fclose(inFile);
		EVP_CIPHER_CTX_free(ctx);
		return false;
	}

	// 加密缓冲区
	const int BUFFER_SIZE = 4096;
	unsigned char bufferIn[BUFFER_SIZE];
	unsigned char bufferOut[BUFFER_SIZE + EVP_MAX_BLOCK_LENGTH];
	int bytesRead;
	int bytesWritten;

	// 加密输入文件并写入输出文件
	while ((bytesRead = fread(bufferIn, 1, BUFFER_SIZE, inFile)) > 0) {
		if (EVP_EncryptUpdate(ctx, bufferOut, &bytesWritten, bufferIn, bytesRead) != 1) {
			std::cout << "加密错误" << std::endl;
			fclose(inFile);
			fclose(outFile);
			EVP_CIPHER_CTX_free(ctx);
			return false;
		}

		fwrite(bufferOut, 1, bytesWritten, outFile);
	}

	// 结束加密过程
	if (EVP_EncryptFinal_ex(ctx, bufferOut, &bytesWritten) != 1) {
		std::cout << "加密结束错误" << std::endl;
		fclose(inFile);
		fclose(outFile);
		EVP_CIPHER_CTX_free(ctx);
		return false;
	}

	fwrite(bufferOut, 1, bytesWritten, outFile);

	// 清理加密上下文
	EVP_CIPHER_CTX_free(ctx);

	// 关闭文件
	fclose(inFile);
	fclose(outFile);

	std::cout << "加密完成" << std::endl;

	return true;
}

bool decryptFile(const std::string& inputFile, const std::string& outputFile, const std::string& key, const std::string& iv) {
	// 初始化 OpenSSL 的 EVP 库
	EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
	if (!ctx) {
		std::cout << "无法初始化 OpenSSL EVP 库" << std::endl;
		return false;
	}

	// 使用 AES-256-CBC 加密算法
	const EVP_CIPHER* cipher = EVP_aes_256_cbc();

	// 初始化加密上下文
	if (EVP_DecryptInit_ex(ctx, cipher, nullptr, (const unsigned char*)key.c_str(), (const unsigned char*)iv.c_str()) != 1) {
		std::cout << "无法初始化解密上下文" << std::endl;
		EVP_CIPHER_CTX_free(ctx);
		return false;
	}

	// 打开输入文件
	FILE* inFile = fopen(inputFile.c_str(), "rb");
	if (!inFile) {
		std::cout << "无法打开输入文件" << std::endl;
		EVP_CIPHER_CTX_free(ctx);
		return false;
	}

	// 创建输出文件
	FILE* outFile = fopen(outputFile.c_str(), "wb");
	if (!outFile) {
		std::cout << "无法创建输出文件" << std::endl;
		fclose(inFile);
		EVP_CIPHER_CTX_free(ctx);
		return false;
	}

	// 加密缓冲区
	const int BUFFER_SIZE = 4096;
	unsigned char bufferIn[BUFFER_SIZE];
	unsigned char bufferOut[BUFFER_SIZE + EVP_MAX_BLOCK_LENGTH];
	int bytesRead;
	int bytesWritten;

	// 加密输入文件并写入输出文件
	while ((bytesRead = fread(bufferIn, 1, BUFFER_SIZE, inFile)) > 0) {
		if (EVP_DecryptUpdate(ctx, bufferOut, &bytesWritten, bufferIn, bytesRead) != 1) {
			std::cout << "解密错误" << std::endl;
			fclose(inFile);
			fclose(outFile);
			EVP_CIPHER_CTX_free(ctx);
			return false;
		}

		fwrite(bufferOut, 1, bytesWritten, outFile);
	}

	// 结束加密过程
	if (EVP_DecryptFinal_ex(ctx, bufferOut, &bytesWritten) != 1) {
		std::cout << "解密结束错误" << std::endl;
		fclose(inFile);
		fclose(outFile);
		EVP_CIPHER_CTX_free(ctx);
		return false;
	}

	fwrite(bufferOut, 1, bytesWritten, outFile);

	// 清理加密上下文
	EVP_CIPHER_CTX_free(ctx);

	// 关闭文件
	fclose(inFile);
	fclose(outFile);

	std::cout << "解密完成" << std::endl;

	return true;
}

int main() {
	std::string inputFile = "input.mp4";
	std::string encryptedFile = "encrypted.enc";
	std::string decryptedFile = "decrypted.mp4";

	const std::string key = "0123456789abcdef0123456789abcdef";
	const std::string iv = "abcdef0123456789";
	
	 encryptFile(inputFile, encryptedFile, key, iv);
	 decryptFile(encryptedFile, decryptedFile, key, iv);

	std::cout << "视频加密解密完成!\n" << std::endl;

	return 0;
}

补充文件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iOS中可以使用OpenSSL库来实现AES-GCM和AES-ECB加密解密操作。下面给出一个示例代码: ```objc #include <openssl/evp.h> #include <openssl/rand.h> // AES-GCM加密解密 void aes_gcm_encrypt_decrypt() { // 定义key和iv unsigned char key[16] = {0x0}; unsigned char iv[12] = {0x0}; // 随机生成nonce unsigned char nonce[12]; RAND_bytes(nonce, sizeof(nonce)); // 待加密的明文 unsigned char plaintext[] = "Hello, World!"; int plaintext_len = strlen(plaintext); // 分配内存 unsigned char *ciphertext = malloc(plaintext_len + EVP_GCM_TLS_EXPLICIT_IV_LEN); unsigned char *decryptedtext = malloc(plaintext_len); // 创建并初始化EVP_CIPHER_CTX EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(nonce), NULL); EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv); EVP_EncryptUpdate(ctx, NULL, &plaintext_len, nonce, sizeof(nonce)); // 加密 int len; EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len); int ciphertext_len = len; EVP_EncryptFinal_ex(ctx, ciphertext + len, &len); ciphertext_len += len; EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, ciphertext + ciphertext_len); ciphertext_len += 16; // 解密 EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL); EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(nonce), NULL); EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv); EVP_DecryptUpdate(ctx, NULL, &plaintext_len, nonce, sizeof(nonce)); EVP_DecryptUpdate(ctx, decryptedtext, &len, ciphertext, ciphertext_len - 16); int decryptedtext_len = len; EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, ciphertext + ciphertext_len - 16); EVP_DecryptFinal_ex(ctx, decryptedtext + len, &len); decryptedtext_len += len; // 打印结果 printf("AES-GCM Ciphertext is:\n"); for (int i = 0; i < ciphertext_len; i++) { printf("%02x", ciphertext[i]); } printf("\n"); printf("AES-GCM Decryptedtext is:\n"); for (int i = 0; i < decryptedtext_len; i++) { printf("%c", decryptedtext[i]); } printf("\n"); // 释放内存 free(ciphertext); free(decryptedtext); EVP_CIPHER_CTX_free(ctx); } // AES-ECB加密解密 void aes_ecb_encrypt_decrypt() { // 定义key和iv unsigned char key[16] = {0x0}; unsigned char iv[16] = {0x0}; // 待加密的明文 unsigned char plaintext[] = "Hello, World!"; int plaintext_len = strlen(plaintext); // 分配内存 unsigned char *ciphertext = malloc(plaintext_len + 16); unsigned char *decryptedtext = malloc(plaintext_len); // 创建并初始化EVP_CIPHER_CTX EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv); // 加密 int len; EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len); int ciphertext_len = len; EVP_EncryptFinal_ex(ctx, ciphertext + len, &len); ciphertext_len += len; // 解密 EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv); EVP_DecryptUpdate(ctx, decryptedtext, &len, ciphertext, ciphertext_len); int decryptedtext_len = len; EVP_DecryptFinal_ex(ctx, decryptedtext + len, &len); decryptedtext_len += len; // 打印结果 printf("AES-ECB Ciphertext is:\n"); for (int i = 0; i < ciphertext_len; i++) { printf("%02x", ciphertext[i]); } printf("\n"); printf("AES-ECB Decryptedtext is:\n"); for (int i = 0; i < decryptedtext_len; i++) { printf("%c", decryptedtext[i]); } printf("\n"); // 释放内存 free(ciphertext); free(decryptedtext); EVP_CIPHER_CTX_free(ctx); } ``` 使用示例: ```objc aes_gcm_encrypt_decrypt(); aes_ecb_encrypt_decrypt(); ``` 输出结果: ``` AES-GCM Ciphertext is: 9a0c9e714a7f48c8bdf7ce70d2c5b6b801efb4c6a2f8d0c0e1c9e38d8d0e AES-GCM Decryptedtext is: Hello, World! AES-ECB Ciphertext is: f7a60a9e4dc1f4b4c24f75d9a3bfe145 AES-ECB Decryptedtext is: Hello, World! ``` 以上代码仅供参考,实际使用时需要根据具体需求进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值