记录一个视频加密解密-- AES 基础版

AES是一种广泛使用的对称加密算法,支持128、192和256位密钥,提供高安全性。文章介绍了AES的基本原理,包括字节替换、行移位、列混淆和轮密钥加操作,并提供了使用OpenSSL库的C++加密和解密代码示例。
摘要由CSDN通过智能技术生成

先简单介绍下AES,这里不做详细具体的介绍,具体详细的请自行查找
AES(Advanced Encryption Standard)是一种对称加密算法,用于保护数据的机密性和安全性,是目前应用最广泛的数据加密标准之一。
AES 的设计目标是提供高度安全性、高性能和有效的数据保护。它支持三种密钥长度:128位、192位和256位,其中128位密钥被广泛应用。AES 还支持多种分组模式,如 ECB(电子密码本模式)、CBC(密码块链模式)和CTR(计数器模式),以适应不同的加密需求。
AES 提供了很高的安全性,其强大在于混淆、替换和移动数据的复杂操作,使得密钥和密文之间的关系变得极其复杂,增加了破解难度。目前,没有公开的攻击方法能够有效地破解 AES 加密。

AES 的基本原理是使用相同的密钥进行加密和解密操作,因此被称为"对称加密算法"。它采用了迭代替换和置换运算的结合,将明文分割为固定大小的数据块,并对每个数据块进行加密处理。
AES 算法执行过程如下:

  1. 密钥扩展:根据所选的密钥长度,对输入的密钥进行扩展,生成轮密钥。
  2. 初始轮加密:将明文分成相等大小的数据块(通常为128位),并与第一轮轮密钥进行异或运算。
  3. 迭代执行多个轮次的四步操作:
  • 字节替换(SubBytes):将数据块中的每个字节替换为一个预定义的查找表中的对应字节。
  • 行移位(ShiftRows):根据数据块的行数,进行循环左移操作。
  • 列混淆(MixColumns):通过特定的矩阵乘法,使得每一列的数值相互混淆。
  • 轮密钥加(AddRoundKey):与当前轮次的轮密钥进行异或运算。
  1. 最后一轮的操作不包括列混淆步骤。
    通过上述步骤迭代执行多个轮次,最终生成密文。

安全性注意事项:在使用 AES 时,需要注意以下安全性问题:

  1. 使用强密码:选择足够强度的密钥,并采用适当的密钥管理和保护措施。
  2. 防止侧信道攻击:使用 OpenSSL 提供的安全的实现,并采取相应的防护措施,以防止侧信道攻击,如时钟攻击、功耗分析等。
  3. 选择适当的加密模式:根据应用需求选择合适的加密模式,以提供合适的机密性和完整性保护。

不啰嗦了,下面直接干货 完成测试代码
代码中是使用128位的密钥,也是最常用的

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

void encryptVideo(const std::string& inputFile, const std::string& outputFile, const std::string& key) 
{

	int keyLen = key.size();
	if (keyLen != 16 && keyLen != 24 && keyLen != 32)
	{
		std::cout << "keyLen " << keyLen << std::endl;
		std::cout << "密钥长度不是16/24/32字节,请重新输入" << std::endl;
		return;
	}

	AES_KEY aesKey;
	if (keyLen == 16)
	{
		AES_set_encrypt_key(reinterpret_cast<const unsigned char *>(key.c_str()), 128, &aesKey);
	}
	else if (keyLen == 24)
	{
		AES_set_encrypt_key(reinterpret_cast<const unsigned char *>(key.c_str()), 192, &aesKey);
	}
	else if (keyLen == 32)
	{
		AES_set_encrypt_key(reinterpret_cast<const unsigned char *>(key.c_str()), 256, &aesKey);
	}

	FILE* inputFileStream = fopen(inputFile.c_str(), "rb");
	FILE* outputFileStream = fopen(outputFile.c_str(), "wb");

	unsigned char inBuffer[AES_BLOCK_SIZE];
	unsigned char outBuffer[AES_BLOCK_SIZE];

	size_t bytesRead;
	while ((bytesRead = fread(inBuffer, 1, AES_BLOCK_SIZE, inputFileStream)) > 0) {
		AES_encrypt(inBuffer, outBuffer, &aesKey);
		fwrite(outBuffer, 1, bytesRead, outputFileStream);
	}

	fclose(inputFileStream);
	fclose(outputFileStream);
	std::cout << "视频加密完成!\n" << std::endl;
}

void decryptVideo(const std::string& inputFile, std::string& outputFile, const std::string& key) 
{
	int keyLen = key.size();
	if (keyLen != 16  && keyLen != 24 && keyLen != 32)
	{
		std::cout << "keyLen " << keyLen << std::endl;
		std::cout << "密钥长度不是16/24/32字节,请重新输入" << std::endl;
		return;
	}

	AES_KEY aesKey;
	if (keyLen == 16)
	{
		AES_set_decrypt_key(reinterpret_cast<const unsigned char *>(key.c_str()), 128, &aesKey);
	}
	else if (keyLen == 24)
	{
		AES_set_decrypt_key(reinterpret_cast<const unsigned char *>(key.c_str()), 192, &aesKey);
	}
	else if (keyLen == 32)
	{
		AES_set_decrypt_key(reinterpret_cast<const unsigned char *>(key.c_str()), 256, &aesKey);
	}

	FILE* inputFileStream = fopen(inputFile.c_str(), "rb");
	FILE* outputFileStream = fopen(outputFile.c_str(), "wb");

	unsigned char inBuffer[AES_BLOCK_SIZE];
	unsigned char outBuffer[AES_BLOCK_SIZE];

	size_t bytesRead;
	while ((bytesRead = fread(inBuffer, 1, AES_BLOCK_SIZE, inputFileStream)) > 0) {
		AES_decrypt(inBuffer, outBuffer, &aesKey);
		fwrite(outBuffer, 1, bytesRead, outputFileStream);
	}

	fclose(inputFileStream);
	fclose(outputFileStream);
	std::cout << "视频解密完成!\n" << std::endl;
}

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

	const std::string key = "0123456789abcdef";

	encryptVideo(inputFile, encryptedFile, key);
	decryptVideo(encryptedFile, decryptedFile, key);

	printf("视频加密解密完成!\n");

	return 0;
}

我测试使用的代码可以完成加密和解密的功能
这个是基本的aes加密数据,后面再弄一个加强版的

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值