AES演算法是一種對稱加密演算法,全稱為高級加密標準(Advanced Encryption Standard)。它是一種分組密碼,以`128`比特為一個分組進行加密,其密鑰長度可以是`128`比特、`192`比特或`256`比特,因此可以提供不同等級的安全性。該演算法採用了替代、置換和混淆等技術,以及多... ...
AES演算法是一種對稱加密演算法,全稱為高級加密標準(Advanced Encryption Standard)。它是一種分組密碼,以128
比特為一個分組進行加密,其密鑰長度可以是128
比特、192
比特或256
比特,因此可以提供不同等級的安全性。該演算法採用了替代、置換和混淆等技術,以及多輪加密和密鑰擴展等機制,使得其加密效果優秀,安全性高,被廣泛應用於各種領域中,如數據加密、文件加密、網路安全等。
AES演算法加密和解密使用的密鑰是相同的,該演算法加密和解密速度較快,適用於對大量數據進行加密解密的場景。在實際應用中,通常採用混合加密方式,即使用RSA演算法加密對稱加密演算法中的密鑰,再使用對稱加密演算法加密數據,以保證數據的機密性和加密解密的效率。
AES演算法常用兩種加密模式,即CBC和ECB模式,它們分別具有不同的優缺點。
-
ECB(Electronic Codebook,電子密碼本)模式是最簡單的分組密碼工作模式,將每個明文塊獨立加密,同樣的密鑰加密同樣的明文塊得到的密文也是一樣的,因此容易被攻擊者利用重覆的密文進行分析破解。ECB模式加密效率高,適用於短報文加密,但不適用於長報文加密。
-
CBC(Cipher Block Chaining,密碼塊鏈)模式是一種分組密碼工作模式,先將明文分組,然後對每個分組進行加密,加密時使用上一塊密文作為輸入,因此相同的明文塊在不同位置上得到的密文是不同的,可以防止被攻擊者利用重覆的密文進行分析破解。CBC模式加密效率較低,但適用於長報文加密,因為不同的明文塊之間互相影響,增加了安全性。
在實際應用中,通常採用CBC
模式進行加密,因為它比ECB
模式更安全,但加密效率較低。此外,還有其他的加密模式,如CFB、OFB、CTR
等,不同的加密模式適用於不同的場景,需要根據實際需求進行選擇。
OpenSSL庫提供了對AES
加密的支持,但在使用時讀者還是需要自行封裝一些通用加解密函數,如下代碼片段是筆者常用的一些函數總結,其中aes_cbc_encrypt
函數用於使用CBC模式對特定字元串加密,aes_cbc_decrypt
則使用CBC模式對字元串進行解密,第二個函數AES
函數則是使用OpenSSL
庫預設的加解密函數二次封裝實現的。
#include <iostream>
#include <openssl/err.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/crypto.h>
#include <openssl/pem.h>
extern "C"
{
#include <openssl/applink.c>
}
#pragma comment(lib,"libssl_static.lib")
#pragma comment(lib,"libcrypto.lib")
// CBC模式加密
int aes_cbc_encrypt(char* in, char* key, char* out)
{
if (!in || !key || !out)
return 0;
unsigned char iv[AES_BLOCK_SIZE];
for (int i = 0; i < AES_BLOCK_SIZE; ++i)
iv[i] = 0;
AES_KEY aes;
if (AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
{
return 0;
}
int len = strlen(in);
AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &aes, iv, AES_ENCRYPT);
return 1;
}
// CBC模式解密
int aes_cbc_decrypt(char* in, char* key, char* out)
{
if (!in || !key || !out)
return 0;
// 加密的初始化向量
unsigned char iv[AES_BLOCK_SIZE];
// iv一般設置為全0
for (int i = 0; i < AES_BLOCK_SIZE; ++i)
iv[i] = 0;
AES_KEY aes;
if (AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0)
{
return 0;
}
int len = strlen(in);
AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &aes, iv, AES_DECRYPT);
return 1;
}
// 將加密與解密整合在一起
void AES(unsigned char* InBuff, unsigned char* OutBuff, unsigned char* key, char* Type)
{
if (strcmp(Type, "encode") == 0)
{
AES_KEY AESEncryptKey;
AES_set_encrypt_key(key, 256, &AESEncryptKey);
AES_encrypt(InBuff, OutBuff, &AESEncryptKey);
}
else if (strcmp(Type, "decode") == 0)
{
AES_KEY AESDecryptKey;
AES_set_decrypt_key(key, 256, &AESDecryptKey);
AES_decrypt(InBuff, OutBuff, &AESDecryptKey);
}
}
有了上述演算法封裝,接下來筆者將依次演示這幾種不同的加密函數是如何被應用的,首先簡單介紹一下aes_cbc_encrypt
與aes_cbc_decrypt
這兩個函數都是自己封裝的AES加解密演算法,這兩個演算法參數傳遞保持一致,第一個參數都是指定需要加密的緩衝區,第二個參數則是指定加密所使用的key,第三個參數是處理後的結果。
int main(int argc, char* argv[])
{
char szBuffer[1024] = "hello lyshark";
char szDst[1024] = { 0 };
char szSrc[1024] = { 0 };
// 計算一串密鑰
char key[AES_BLOCK_SIZE] = { 0 };
for (int x = 0; x < AES_BLOCK_SIZE; x++)
{
key[x] = 32 + x;
}
// AES加密
if (aes_cbc_encrypt(szBuffer, key, szDst) != 0)
{
std::cout << "加密後長度: " << strlen(szDst) << std::endl;
}
// AES解密
if (aes_cbc_decrypt(szDst, key, szSrc) != 0)
{
std::cout << "解密內容: " << szSrc << std::endl;
}
system("pause");
return 0;
}
上述代碼片段則是通過AES實現對數據加解密處理的功能,如下是這段代碼的輸出效果;
第二種調用方式是採用API
實現,其中的AES
函數,通過AES_set_encrypt_key
設置加密密鑰,並直接調用AES_encrypt
實現數據加密,反之,通過AES_set_decrypt_key
設置解密密鑰,並調用AES_decrypt
解密,這段代碼調用方式如下所示;
int main(int argc, char* argv[])
{
unsigned char Buffer[1024] = "hello lyshark";
unsigned char EncodeBuf[1024] = { 0 };
unsigned char DecodeBuf[1024] = { 0 };
unsigned char aes_key[32] = { 0 };
// 隨機生成密鑰
for (int x = 0; x < 32; x++)
{
int ch = rand() % 5;
aes_key[x] = (char)ch;
}
AES(Buffer, EncodeBuf, (unsigned char *)aes_key, (char*)"encode");
std::cout << "加密數據長度: " << strlen((char *)EncodeBuf) << std::endl;
AES(EncodeBuf, DecodeBuf, (unsigned char*)aes_key, (char*)"decode");
std::cout << "解密數據: " << DecodeBuf << std::endl;
system("pause");
return 0;
}
如上代碼,通過調用AES
函數時,傳入encode
實現數據加密,傳入decode
實現數據解密,如下圖所示;
本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!