先简单介绍下
AES
,这里不做详细具体的介绍,具体详细的请自行查找
AES(Advanced Encryption Standard)是一种对称加密算法,用于保护数据的机密性和安全性,是目前应用最广泛的数据加密标准之一。
AES 的设计目标是提供高度安全性、高性能和有效的数据保护。它支持三种密钥长度:128位、192位和256位,其中128位密钥被广泛应用。AES 还支持多种分组模式,如 ECB(电子密码本模式)、CBC(密码块链模式)和CTR(计数器模式),以适应不同的加密需求。
AES 提供了很高的安全性,其强大在于混淆、替换和移动数据的复杂操作,使得密钥和密文之间的关系变得极其复杂,增加了破解难度。目前,没有公开的攻击方法能够有效地破解 AES 加密。
AES 的基本原理是使用相同的密钥进行加密和解密操作,因此被称为"对称加密算法"。它采用了迭代替换和置换运算的结合,将明文分割为固定大小的数据块,并对每个数据块进行加密处理。
AES 算法执行过程如下:
- 密钥扩展:根据所选的密钥长度,对输入的密钥进行扩展,生成轮密钥。
- 初始轮加密:将明文分成相等大小的数据块(通常为128位),并与第一轮轮密钥进行异或运算。
- 迭代执行多个轮次的四步操作:
- 字节替换(SubBytes):将数据块中的每个字节替换为一个预定义的查找表中的对应字节。
- 行移位(ShiftRows):根据数据块的行数,进行循环左移操作。
- 列混淆(MixColumns):通过特定的矩阵乘法,使得每一列的数值相互混淆。
- 轮密钥加(AddRoundKey):与当前轮次的轮密钥进行异或运算。
- 最后一轮的操作不包括列混淆步骤。
通过上述步骤迭代执行多个轮次,最终生成密文。
安全性注意事项:在使用 AES 时,需要注意以下安全性问题:
- 使用强密码:选择足够强度的密钥,并采用适当的密钥管理和保护措施。
- 防止侧信道攻击:使用 OpenSSL 提供的安全的实现,并采取相应的防护措施,以防止侧信道攻击,如时钟攻击、功耗分析等。
- 选择适当的加密模式:根据应用需求选择合适的加密模式,以提供合适的机密性和完整性保护。
不啰嗦了,下面直接干货 完成测试代码
代码中是使用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加密数据,后面再弄一个加强版的