欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++ CryptoPP使用AES實現(xiàn)加解密詳解

 更新時間:2023年11月30日 13:57:22   作者:微軟技術(shù)分享  
Crypto++ (CryptoPP) 是一個用于密碼學(xué)和加密的 C++ 庫,提供了大量的密碼學(xué)算法和功能,這篇文章主要為大家介紹了C++ CryptoPP如何使用AES實現(xiàn)加解密,需要的可以參考下

Crypto++ (CryptoPP) 是一個用于密碼學(xué)和加密的 C++ 庫。它是一個開源項目,提供了大量的密碼學(xué)算法和功能,包括對稱加密、非對稱加密、哈希函數(shù)、消息認(rèn)證碼 (MAC)、數(shù)字簽名等。Crypto++ 的目標(biāo)是提供高性能和可靠的密碼學(xué)工具,以滿足軟件開發(fā)中對安全性的需求。

高級加密標(biāo)準(zhǔn)(Advanced Encryption Standard,AES)是一種對稱密鑰加密標(biāo)準(zhǔn),用于保護(hù)電腦上的敏感數(shù)據(jù)。AES是由美國國家標(biāo)準(zhǔn)與技術(shù)研究院(NIST)于2001年確定的,它取代了過時的數(shù)據(jù)加密標(biāo)準(zhǔn)(Data Encryption Standard,DES)。

以下是AES加密算法的主要特點和概述:

  • 對稱密鑰算法: AES是一種對稱密鑰算法,意味著相同的密鑰用于加密和解密數(shù)據(jù)。這就要求通信雙方在通信前共享密鑰,并確保其保密性。
  • 分組密碼: AES將明文數(shù)據(jù)分成固定大小的塊(128比特),然后對每個塊進(jìn)行獨立的加密。這個固定大小的塊稱為分組。AES支持多種分組長度,包括128比特、192比特和256比特。
  • 輪數(shù): AES加密算法的安全性與其輪數(shù)相關(guān)。輪數(shù)表示對數(shù)據(jù)塊的處理循環(huán)次數(shù),不同密鑰長度的AES使用不同數(shù)量的輪數(shù)。通常,128比特密鑰使用10輪,192比特密鑰使用12輪,256比特密鑰使用14輪。
  • 密鑰長度: AES支持多種密鑰長度,包括128比特、192比特和256比特。密鑰長度的選擇直接影響加密算法的安全性。
  • SubBytes、ShiftRows、MixColumns和AddRoundKey: 這些是AES加密算法中的四個主要操作,它們通過多輪迭代來加密數(shù)據(jù)。SubBytes和ShiftRows引入非線性性,MixColumns和AddRoundKey提供了擴(kuò)散和混淆。
  • 強(qiáng)安全性: AES被廣泛認(rèn)為是一種安全、可靠的加密算法。它經(jīng)過廣泛的密碼分析和評估,并且在許多應(yīng)用中得到了廣泛的應(yīng)用,包括加密通信、文件加密和硬件加密。

總體而言,AES是一種高效、安全且廣泛應(yīng)用的加密算法,適用于多種應(yīng)用場景。其在加密強(qiáng)度和性能之間取得了良好的平衡,因此成為許多信息安全應(yīng)用的首選算法。

使用AES算法

AES(Advanced Encryption Standard)廣泛應(yīng)用于保護(hù)敏感數(shù)據(jù)的加密和解密過程。以下是AES算法的概述:

1. 對稱加密算法

AES是一種對稱加密算法,這意味著加密和解密都使用相同的密鑰。密鑰是保護(hù)數(shù)據(jù)安全的關(guān)鍵,因此對稱加密算法需要確保密鑰的安全分發(fā)和管理。

2. 密鑰長度

AES支持不同長度的密鑰,包括128位、192位和256位。密鑰長度越長,通常意味著更高的安全性,但也可能導(dǎo)致加密和解密的計算成本增加。

3. 塊加密算法

AES是塊加密算法,它按照固定大小的數(shù)據(jù)塊(128位)進(jìn)行加密。加密和解密的過程都是對這些數(shù)據(jù)塊的操作。

4. 加解密過程

加密:

  • 數(shù)據(jù)分塊:將明文分成固定大小的數(shù)據(jù)塊(128位)。
  • 初始輪密鑰加:將明文和初始密鑰進(jìn)行一次簡單的混淆操作。
  • 輪加密:通過多輪的替代和置換操作(SubBytes、ShiftRows、MixColumns、AddRoundKey),對數(shù)據(jù)塊進(jìn)行混淆。
  • 最終輪:在最后一輪中,省略MixColumns操作。
  • 得到密文。

解密:

  • 初始輪密鑰解:將密文和初始密鑰進(jìn)行一次簡單的混淆操作。
  • 輪解密:通過多輪的逆操作(InvSubBytes、InvShiftRows、InvMixColumns、AddRoundKey),對數(shù)據(jù)塊進(jìn)行逆操作。
  • 最終輪:在最后一輪中,省略InvMixColumns操作。
  • 得到明文。

5. 使用場景

AES廣泛用于保護(hù)敏感數(shù)據(jù),如文件、數(shù)據(jù)庫、網(wǎng)絡(luò)通信等。它是許多安全協(xié)議和標(biāo)準(zhǔn)的基礎(chǔ),包括TLS(安全套接層)、IPsec(Internet協(xié)議安全)等。

6. 安全性

AES被廣泛接受并認(rèn)為是安全可靠的加密算法。密鑰長度的選擇對安全性至關(guān)重要,一般建議使用128位、192位或256位的密鑰以滿足特定安全需求。

總體而言,AES作為一種高效且安全的對稱加密算法,在現(xiàn)代加密通信中扮演著重要的角色。AES的使用需要引入頭文件#include <aes.h>其他部分與《C++ 通過CryptoPP計算Hash值》文章中的頭文件引入保持一致。

如下AESEncrypt是一個使用AES算法進(jìn)行加密的函數(shù)。下面是對函數(shù)的主要步驟的注釋:

AES加密對象初始化:

  • 創(chuàng)建AESEncryption對象用于AES加密。
  • 定義AES加密需要的數(shù)據(jù)塊:inBlock(輸入數(shù)據(jù)塊)、outBlock(輸出數(shù)據(jù)塊)、xorBlock(異或數(shù)據(jù)塊)。

計算加密數(shù)據(jù)塊大?。?/strong>

計算需要的加密數(shù)據(jù)塊數(shù)量,考慮到原始數(shù)據(jù)大小可能不是AES塊大小的整數(shù)倍。

分配加密后的數(shù)據(jù)緩沖區(qū):

根據(jù)計算得到的加密數(shù)據(jù)塊大小分配內(nèi)存。

設(shè)置AES加密密鑰:

調(diào)用SetKey函數(shù)設(shè)置AES加密密鑰。

AES加密過程:

  • 循環(huán)處理原始數(shù)據(jù)塊,每次處理一個AES塊大小的數(shù)據(jù)。
  • 將原始數(shù)據(jù)塊拷貝到輸入數(shù)據(jù)塊。
  • 使用AES算法進(jìn)行加密。
  • 將加密后的數(shù)據(jù)塊拷貝到輸出緩沖區(qū)。

返回加密結(jié)果:

返回加密后的數(shù)據(jù)緩沖區(qū)和大小。

請注意,在實際使用中,要確保釋放了分配的內(nèi)存,以防止內(nèi)存泄漏。

BOOL AESEncrypt(BYTE *pOriginalData, DWORD dwOriginalDataSize, BYTE *pAESKey, DWORD dwAESKeySize, BYTE **ppEncryptData, DWORD *pdwEncryptData)
{
	// 定義AES加密需要的數(shù)據(jù)塊
	AESEncryption aesEncryptor;
	// 加密原文數(shù)據(jù)塊
	unsigned char inBlock[AES::BLOCKSIZE];
	// 加密后密文數(shù)據(jù)塊
	unsigned char outBlock[AES::BLOCKSIZE];
	// 必須設(shè)定全為0
	unsigned char xorBlock[AES::BLOCKSIZE];

	DWORD dwOffset = 0;
	BYTE *pEncryptData = NULL;
	DWORD dwEncryptDataSize = 0;

	// 計算需要的加密數(shù)據(jù)塊大小, 并按 128位 即 16字節(jié) 對齊, 不夠則 填充0 對齊
	// 商
	DWORD dwQuotient = dwOriginalDataSize / AES::BLOCKSIZE;
	// 余數(shù)
	DWORD dwRemaind = dwOriginalDataSize % AES::BLOCKSIZE;
	if (0 != dwRemaind)
	{
		dwQuotient++;
	}

	// 申請動態(tài)內(nèi)存
	dwEncryptDataSize = dwQuotient * AES::BLOCKSIZE;

	// 分配加密后的數(shù)據(jù)緩沖區(qū)
	pEncryptData = new BYTE[dwEncryptDataSize];
	if (NULL == pEncryptData)
	{
		return FALSE;
	}

	// 設(shè)置AES加密密鑰
	aesEncryptor.SetKey(pAESKey, dwAESKeySize);

	do
	{
		// 初始化數(shù)據(jù)塊
		RtlZeroMemory(inBlock, AES::BLOCKSIZE);
		RtlZeroMemory(xorBlock, AES::BLOCKSIZE);
		RtlZeroMemory(outBlock, AES::BLOCKSIZE);

		// 獲取加密塊
		if (dwOffset <= (dwOriginalDataSize - AES::BLOCKSIZE))
		{
			RtlCopyMemory(inBlock, (PVOID)(pOriginalData + dwOffset), AES::BLOCKSIZE);
		}
		else
		{
			RtlCopyMemory(inBlock, (PVOID)(pOriginalData + dwOffset), (dwOriginalDataSize - dwOffset));
		}

		// 使用AES算法進(jìn)行加密
		aesEncryptor.ProcessAndXorBlock(inBlock, xorBlock, outBlock);

		// 將加密后的數(shù)據(jù)塊拷貝到輸出緩沖區(qū)
		RtlCopyMemory((PVOID)(pEncryptData + dwOffset), outBlock, AES::BLOCKSIZE);

		// 更新數(shù)據(jù)
		dwOffset = dwOffset + AES::BLOCKSIZE;
		dwQuotient--;
	} while (0 < dwQuotient);

	// 返回數(shù)據(jù)
	*ppEncryptData = pEncryptData;
	*pdwEncryptData = dwEncryptDataSize;

	return TRUE;
}

如下AESDecrypt是一個使用AES算法進(jìn)行解密的函數(shù)。以下是對函數(shù)的主要步驟的注釋:

AES解密對象初始化:

  • 創(chuàng)建AESDecryption對象用于AES解密。
  • 定義AES解密需要的數(shù)據(jù)塊:inBlock(輸入數(shù)據(jù)塊)、outBlock(輸出數(shù)據(jù)塊)、xorBlock(異或數(shù)據(jù)塊)。

計算解密數(shù)據(jù)塊大?。?/strong>

計算需要的解密數(shù)據(jù)塊數(shù)量,考慮到加密數(shù)據(jù)大小可能不是AES塊大小的整數(shù)倍。

分配解密后的數(shù)據(jù)緩沖區(qū):

根據(jù)計算得到的解密數(shù)據(jù)塊大小分配內(nèi)存。

設(shè)置AES解密密鑰:

調(diào)用SetKey函數(shù)設(shè)置AES解密密鑰。

AES解密過程:

  • 循環(huán)處理加密數(shù)據(jù)塊,每次處理一個AES塊大小的數(shù)據(jù)。
  • 將加密數(shù)據(jù)塊拷貝到輸入數(shù)據(jù)塊。
  • 使用AES算法進(jìn)行解密。
  • 將解密后的數(shù)據(jù)塊拷貝到輸出緩沖區(qū)。

返回解密結(jié)果:

返回解密后的數(shù)據(jù)緩沖區(qū)和大小。

請注意,在實際使用中,要確保釋放了分配的內(nèi)存,以防止內(nèi)存泄漏。

BOOL AESDecrypt(BYTE *pEncryptData, DWORD dwEncryptData, BYTE *pAESKey, DWORD dwAESKeySize, BYTE **ppDecryptData, DWORD *pdwDecryptData)
{
	// 定義AES解密需要的數(shù)據(jù)塊
	AESDecryption aesDecryptor;				
	// 解密密文數(shù)據(jù)塊
	unsigned char inBlock[AES::BLOCKSIZE];		
	// 解密后后明文數(shù)據(jù)塊
	unsigned char outBlock[AES::BLOCKSIZE];			
	// 必須設(shè)定全為0
	unsigned char xorBlock[AES::BLOCKSIZE];						
	DWORD dwOffset = 0;
	BYTE *pDecryptData = NULL;
	DWORD dwDecryptDataSize = 0;

	// 計算密文長度, 并按 128位 即 16字節(jié) 對齊, 不夠則填充0對齊
	// 商
	DWORD dwQuotient = dwEncryptData / AES::BLOCKSIZE;
	// 余數(shù)
	DWORD dwRemaind = dwEncryptData % AES::BLOCKSIZE;		
	if (0 != dwRemaind)
	{
		dwQuotient++;
	}

	// 分配解密后的數(shù)據(jù)緩沖區(qū)
	dwDecryptDataSize = dwQuotient * AES::BLOCKSIZE;
	pDecryptData = new BYTE[dwDecryptDataSize];
	if (NULL == pDecryptData)
	{
		return FALSE;
	}

	// 設(shè)置AES解密密鑰
	aesDecryptor.SetKey(pAESKey, dwAESKeySize);

	do
	{
		// 初始化數(shù)據(jù)塊
		RtlZeroMemory(inBlock, AES::BLOCKSIZE);
		RtlZeroMemory(xorBlock, AES::BLOCKSIZE);
		RtlZeroMemory(outBlock, AES::BLOCKSIZE);

		// 將加密數(shù)據(jù)塊拷貝到輸入數(shù)據(jù)塊
		if (dwOffset <= (dwDecryptDataSize - AES::BLOCKSIZE))
		{
			RtlCopyMemory(inBlock, (PVOID)(pEncryptData + dwOffset), AES::BLOCKSIZE);
		}
		else
		{
			RtlCopyMemory(inBlock, (PVOID)(pEncryptData + dwOffset), (dwEncryptData - dwOffset));
		}

		// 使用AES算法進(jìn)行解密
		aesDecryptor.ProcessAndXorBlock(inBlock, xorBlock, outBlock);

		// 將解密后的數(shù)據(jù)塊拷貝到輸出緩沖區(qū)
		RtlCopyMemory((PVOID)(pDecryptData + dwOffset), outBlock, AES::BLOCKSIZE);

		// 更新數(shù)據(jù)
		dwOffset = dwOffset + AES::BLOCKSIZE;
		dwQuotient--;
	} while (0 < dwQuotient);

	// 返回數(shù)據(jù)
	*ppDecryptData = pDecryptData;
	*pdwDecryptData = dwDecryptDataSize;

	return TRUE;
}

AESEncrypt 函數(shù)用于對輸入的原始數(shù)據(jù)進(jìn)行AES加密,加密使用指定的AES密鑰。函數(shù)通過參數(shù)返回加密后的數(shù)據(jù)和數(shù)據(jù)大小。

函數(shù)原型:

BOOL AESEncrypt(
    BYTE *pOriginalData,     // [in] 原始數(shù)據(jù)的指針
    DWORD dwOriginalDataSize, // [in] 原始數(shù)據(jù)的大小
    BYTE *pAESKey,           // [in] AES加密密鑰的指針
    DWORD dwAESKeySize,       // [in] AES加密密鑰的大小
    BYTE **ppEncryptData,    // [out] 指向指針的指針,用于存儲加密后的數(shù)據(jù)
    DWORD *pdwEncryptData    // [out] 指向DWORD的指針,用于存儲加密后的數(shù)據(jù)大小
);
  • pOriginalData: 指向要加密的原始數(shù)據(jù)的指針。
  • dwOriginalDataSize: 原始數(shù)據(jù)的大小。
  • pAESKey: 指向用于AES加密的密鑰的指針。
  • dwAESKeySize: AES加密密鑰的大小。
  • ppEncryptData: 指向指針的指針,用于存儲加密后的數(shù)據(jù)。該指針需要在函數(shù)外釋放分配的內(nèi)存。
  • pdwEncryptData: 指向DWORD的指針,用于存儲加密后的數(shù)據(jù)大小。

函數(shù)返回一個BOOL值,表示操作是否成功。如果函數(shù)返回TRUE,則表示加密成功,否則表示加密失敗。

AESDecrypt 函數(shù)用于對輸入的加密后的數(shù)據(jù)進(jìn)行AES解密,解密使用指定的AES密鑰。函數(shù)通過參數(shù)返回解密后的數(shù)據(jù)和數(shù)據(jù)大小。

函數(shù)原型:

BOOL AESDecrypt(
    BYTE *pEncryptData,      // [in] 加密后的數(shù)據(jù)的指針
    DWORD dwEncryptDataSize, // [in] 加密后的數(shù)據(jù)的大小
    BYTE *pAESKey,           // [in] AES解密密鑰的指針
    DWORD dwAESKeySize,       // [in] AES解密密鑰的大小
    BYTE **ppDecryptData,    // [out] 指向指針的指針,用于存儲解密后的數(shù)據(jù)
    DWORD *pdwDecryptData    // [out] 指向DWORD的指針,用于存儲解密后的數(shù)據(jù)大小
);
  • pEncryptData: 指向要解密的加密后數(shù)據(jù)的指針。
  • dwEncryptDataSize: 加密后數(shù)據(jù)的大小。
  • pAESKey: 指向用于AES解密的密鑰的指針。
  • dwAESKeySize: AES解密密鑰的大小。
  • ppDecryptData: 指向指針的指針,用于存儲解密后的數(shù)據(jù)。該指針需要在函數(shù)外釋放分配的內(nèi)存。
  • pdwDecryptData: 指向DWORD的指針,用于存儲解密后的數(shù)據(jù)大小。

函數(shù)返回一個BOOL值,表示操作是否成功。如果函數(shù)返回TRUE,則表示解密成功,否則表示解密失敗。

調(diào)用時通過AESEncrypt加密數(shù)據(jù),AESDecrypt則用于解密數(shù)據(jù);

void ShowData(BYTE *pData, DWORD dwSize)
{
	for (int i = 0; i < dwSize; i++)
	{
		if ((0 != i) &&
			(0 == i % 16))
		{
			printf("\n");
		}
		else if ((0 != i) &&
			(0 == i % 8))
		{
			printf(" ");
		}

		printf("%02X ", pData[i]);
	}
	printf("\n");
}

int main(int argc, char* argv[])
{
	BYTE *pEncryptData = NULL;
	DWORD dwEncryptDataSize = 0;
	BYTE *pDecryptData = NULL;
	DWORD dwDecryptDataSize = 0;
	char szOriginalData[] = "It's better to be alone than to be with someone you're not happy to be with.";

	char szAESKey[] = "ABCDEFGHIJKIMNOP";
	BOOL  bRet = FALSE;

	// 加密
	bRet = AESEncrypt((BYTE *)szOriginalData, (1 + ::lstrlen(szOriginalData)), (BYTE *)szAESKey, ::lstrlen(szAESKey), &pEncryptData, &dwEncryptDataSize);
	if (FALSE == bRet)
	{
		return 1;
	}

	// 解密
	bRet = AESDecrypt(pEncryptData, dwEncryptDataSize, (BYTE *)szAESKey, ::lstrlen(szAESKey), &pDecryptData, &dwDecryptDataSize);
	if (FALSE == bRet)
	{
		return 2;
	}

	// 顯示
	printf("原文數(shù)據(jù):\n");
	ShowData((BYTE *)szOriginalData, (1 + ::lstrlen(szOriginalData)));
	printf("密文數(shù)據(jù):\n");
	ShowData(pEncryptData, dwEncryptDataSize);
	printf("解密后數(shù)據(jù):\n");
	ShowData(pDecryptData, dwDecryptDataSize);

	// 釋放內(nèi)存
	delete[]pEncryptData;
	pEncryptData = NULL;
	delete[]pDecryptData;
	pDecryptData = NULL;

	system("pause");
	return 0;
}

運(yùn)行后對szOriginalData中的數(shù)據(jù)進(jìn)行加密,密鑰是szAESKey中的長度,如下圖所示;

到此這篇關(guān)于C++ CryptoPP使用AES實現(xiàn)加解密詳解的文章就介紹到這了,更多相關(guān)C++加解密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++簡易通訊錄系統(tǒng)實現(xiàn)流程詳解

    C++簡易通訊錄系統(tǒng)實現(xiàn)流程詳解

    這篇文章主要為大家介紹了C語言簡易版通訊錄的具體實現(xiàn)流程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 簡單實現(xiàn)C++復(fù)數(shù)計算器

    簡單實現(xiàn)C++復(fù)數(shù)計算器

    這篇文章主要為大家詳細(xì)介紹了C++簡單實現(xiàn)復(fù)數(shù)計算器的的相關(guān)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-06-06
  • QT利用QProcess獲取計算機(jī)硬件信息

    QT利用QProcess獲取計算機(jī)硬件信息

    本文介紹利用QProcess獲取計算機(jī)的CPU、主板、硬盤等電腦相關(guān)硬件信息。文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)QT有一定的幫助,感興趣的可以了解一下
    2022-06-06
  • C++實現(xiàn)LeetCode(147.鏈表插入排序)

    C++實現(xiàn)LeetCode(147.鏈表插入排序)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(147.鏈表插入排序),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C語言函數(shù)指針數(shù)組實現(xiàn)計算器功能

    C語言函數(shù)指針數(shù)組實現(xiàn)計算器功能

    這篇文章主要通過C語言函數(shù)指針數(shù)組實現(xiàn)了計算器的功能,是一個很好而且流程詳細(xì)的小例子,感興趣的新手朋友們可以自己動手也寫一遍
    2022-04-04
  • 查找算法之二分查找的C++實現(xiàn)

    查找算法之二分查找的C++實現(xiàn)

    今天小編就為大家分享一篇關(guān)于查找算法之二分查找的C++實現(xiàn),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • C++線程中幾類鎖的詳解

    C++線程中幾類鎖的詳解

    這篇文章主要為大家介紹了C++線程中幾類鎖,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • OpenCV實現(xiàn)雙邊濾波算法

    OpenCV實現(xiàn)雙邊濾波算法

    這篇文章主要為大家詳細(xì)介紹了OpenCV實現(xiàn)雙邊濾波算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 基于C語言自制華容道游戲的示例代碼

    基于C語言自制華容道游戲的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C語言自制華容道游戲,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C語言有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下
    2023-03-03
  • C語言中數(shù)據(jù)是如何存儲在內(nèi)存中的

    C語言中數(shù)據(jù)是如何存儲在內(nèi)存中的

    使用編程語言進(jìn)行編程時,需要用到各種變量來存儲各種信息。變量保留的是它所存儲的值的內(nèi)存位置。這意味著,當(dāng)您創(chuàng)建一個變量時,就會在內(nèi)存中保留一些空間。您可能需要存儲各種數(shù)據(jù)類型的信息,操作系統(tǒng)會根據(jù)變量的數(shù)據(jù)類型,來分配內(nèi)存和決定在保留內(nèi)存中存儲什么
    2022-04-04

最新評論