c++ AES代码

本文详细介绍了如何在C++中实现AES加密算法,包括密钥设置、加密和解密过程,适合对C++和加密技术感兴趣的读者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#ifndef _ST_AES_H
#define _ST_AES_H

////////////////////////////////////////////////////////////////////////////
//	如果需要AES加密、解密在不同平台如PHP,JAVA等互通,必须要保证三个地方参数
//	统一,加密算法:均为AES;加密模式:CBC,CFB,ECB,OFB,PCBC其中之一;
//	填充模式;NoPadding,PKCS5Padding,ISO10126Padding其中之一.
//	注意:CBC,ECB,PCBC加密模式是不支持NoPadding填充模式的
//	
//	填充模式:
//	AES加密数据以16字节为单位,如果数据不满16字节则根据选择的模式进行填充。
//	NoPadding:不进行填充,保持数据原始长度
//	PKCS5Padding:使用16-数据长度的数值填充剩余的字节
//	ISO10126Padding:使用随机数据填充剩余字节
//	
//	算法/模式/填充                16字节加密后数据长度        不满16字节加密后长度
//	AES/CBC/NoPadding             16                          不支持
//	AES/CBC/PKCS5Padding          32                          16
//	AES/CBC/ISO10126Padding       32                          16
//	AES/CFB/NoPadding             16                          原始数据长度
//	AES/CFB/PKCS5Padding          32                          16
//	AES/CFB/ISO10126Padding       32                          16
//	AES/ECB/NoPadding             16                          不支持
//	AES/ECB/PKCS5Padding          32                          16
//	AES/ECB/ISO10126Padding       32                          16
//	AES/OFB/NoPadding             16                          原始数据长度
//	AES/OFB/PKCS5Padding          32                          16
//	AES/OFB/ISO10126Padding       32                          16
//	AES/PCBC/NoPadding            16                          不支持
//	AES/PCBC/PKCS5Padding         32                          16
//	AES/PCBC/ISO10126Padding      32                          16
///////////////////////////////////////////////////////////////////////////

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <memory.h>

enum KEYSIZE{
   
   KS_128,KS_192,KS_256}; /* 密钥长度 */
enum PADDINGMODE{
   
   NOPADDING,PKCS5PADDING,ISO12106PADDING};	/*填充模式*/

class CAES
{
   
   
public:
	/* 缺省构造函数 */
	CAES();

	/* 构造函数,初始化设置密钥长度,密钥及其长度 */
	CAES(KEYSIZE keySize,unsigned char* key,int iSize);

	/* 析构函数 */
	~CAES();

public:
	/* 设置参数 */
	void SetParams(KEYSIZE keySize,unsigned char* key,int isize);

	/* AES加密 */
	void Encrypt(void* in,unsigned long nsize,void* out,void* key,int iSize,KEYSIZE keySize);

	/* AES解密 */
	void Decrypt(void* in,unsigned long nsize,void* out,void* key,int iSize,KEYSIZE keySize);

	/* AES加密(带随机数) */
	void Encrypt2(void* in,unsigned long nsize,void* out,unsigned long& outSize,void* key,int iSize,KEYSIZE keySize,int RandNum = 0);

	/* AES解密 */
	void Decrypt2(void* in,unsigned long nsize,void* out,void* key,int iSize,KEYSIZE keySize);

	/* 清空所有资源 */
	void Clear();

protected:
	/* 初始化密钥 */
	void InitializeKey(unsigned char* key,int keysize);

	/* 初始化轮数 */
	void InitializeRcon();

	/* 计算密钥调度表 */
	void KeyExpansion(void *key);

	/* 轮密钥加 */
	void AddRoundKey(const int round);

	/* 字节替换 */
	void SubBytes(unsigned char bytes[]);

	/* 循环左移 */
	unsigned char* RowBytes(unsigned char bytes[]);
	
	/* 行位移变换 */
	void ShiftRows(void);

	/* 列混合变换 */
	void MixColumns(void);
	
	/* 伽罗瓦域运算 */
	unsigned char gfmultby01(const unsigned char b);
	unsigned char gfmultby02(const unsigned char b);
	unsigned char gfmultby03(const unsigned char b);
	unsigned char gfmultby09(const unsigned char b);
	unsigned char gfmultby0b(const unsigned char b);
	unsigned char gfmultby0d(const unsigned char b);
	unsigned char gfmultby0e(const unsigned char b);

	/* 逆字节替换 */
	void InvSubBytes(unsigned char bytes[]);

	/* 逆行位移变换 */
	void InvShiftRows(void);

	/* 逆列混合变换 */
	void InvMixColumns(void);

	/* 加密 */
	void Cipher(void *in,void *out);

	/* 解密 */
	void InvCipher(void *in,void *out);

	/* 移位 */
	int URS(int a,int b,bool c = true);

	/* 生成随机数 */
	int RangedRandDemo(int range_min, int range_max);

	/* 检查字符串是否为合法16进制串 */
	bool IsNotValidHexStr(const char* pucCharStr);

protected:
	/* 幂函数 */
	inline int pow(int base, int exp) ;

	/* 向下舍入 */
	inline int asmifloor(float f) ;

	/* 向上舍入 */
	inline int asmiceil(float f) ;

public:
	/* 16进制字串----->字符串 */
	static void HexStr2CharStr(char const* pszHexStr, int iSize,unsigned char* pucCharStr);

	/* 字符串----->十六进制字串 */
	static void CharStr2HexStr(unsigned char* pucCharStr, int iSize,char* pszHexStr);

	/* 16进制----->字符 */
	static void Hex2Char(char const* szHex, unsigned char& rch);

	/* 字符----->16进制 */
	static void Char2Hex(unsigned char ch, char* szHex);

	/* 加密 */
	static char* AESEncrypt(void* plainTextBuf,unsigned long bufLen,char** pCipherTxt,void* key,unsigned long keyLen,KEYSIZE keySize = KS_128,int RandNum = 0);

	/* 解密 */
	static char* AESDecrypt(char* cipherText,char** PlainTxt,void* key,unsigned long keyLen,KEYSIZE keySize = KS_128);

	/*加密之后输出Base64结果*/
	static char* AESEncryptOutputBase64Code(void* plainTextBuf,unsigned long bufLen,char** pCipherTxt,void* key,unsigned long keyLen,KEYSIZE keySize = KS_128);

	static wchar_t* AESDecryptOutputBase64Code(void* pCipherTxt,unsigned long bufLen,wchar_t * plainTextBuf,void* key,unsigned long keyLen,KEYSIZE keySize = KS_128);
	static char* AESDecryptOutputBase64Code(void* pCipherTxt,unsigned long bufLen,char* plainTextBuf,void* key,unsigned long keyLen,KEYSIZE keySize = KS_128);
private:
	int m_Nr;				//轮数
	int m_Nb;				//分组长度
	int m_Nk;				//密钥长度
	int m_Mode;				//填充模式
	
	unsigned char* m_w;			//密钥调度表,每次取出Nb个密字,共需要取Nr+1轮,轮数=Nb+6
	unsigned char* m_State;		//加密数据块,每次取行,Nb列
	unsigned char* m_key;			//密钥
	unsigned char* m_rcon;		//轮常数表
};

/*******************************************************
* 函数名: pow
* 函数功能: 幂函数
* 参数个数: 2
**** @Param[IN]: base ---- 基数
**** @Param[OUT]: exp ---- 幂指数
* 返回值: 返回幂值
*******************************************************/
inline int CAES::pow( int base, int exp )
{
   
   
	int r=1;

	if ( exp>0 )
	{
   
   
		for (;;)
		{
   
   
			if ( exp & 1 ) 
				r *= base;

			exp >>= 1;

			if (exp==0) break;

			base *= base;
		}
	}

	return r;
}

/*******************************************************
* 函数名: asmifloor
* 函数功能: 向下舍入
* 参数个数: 1
**** @Param[IN]: f ---- 浮点数
* 返回值: 该浮点数的向下舍入整数
*******************************************************/
inline int CAES::asmifloor( float f )
{
   
   
	static float Half = 0.5;
	int i; 

	__asm fld [f]				// 取浮点数,压入栈顶
	__asm fsub [Half]		// 浮点数减法
	__asm fistp [i]			// 将浮点数以整数形式放入操作数中

	return i;
}

/*******************************************************
* 函数名: asmiceil
* 函数功能: 向上舍入
* 参数个数: 1
**** @Param[IN]: f ---- 浮点数
* 返回值: 该浮点数的向上舍入整数
*******************************************************/
inline int CAES::asmiceil( float f )
{
   
   
	static float Half = 0.5;
	int i; 

	__asm fld [f]
	__asm fadd [Half]
	__asm fistp [i]

	return i;
}

#endif // _ST_AES_H
#include "STAES.h"
#include "Base64Encoder.h"
/***********************************************************************
* 全局变量申明
***********************************************************************/
//S盒
static unsigned char SBox[16][16] = 
{
   
   
				/* 0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f */
	/*0*/  {
   
   0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76},
	/*1*/  {
   
   0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0},
	/*2*/  {
   
   0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15},
	/*3*/  {
   
   0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75},
	/*4*/  {
   
   0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84},
	/*5*/  {
   
   0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf},
	/*6*/  {
   
   0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8},
	/*7*/  {
   
   0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2},
	/*8*/  {
   
   0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73},
	/*9*/  {
   
   0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb},
	/*a*/  {
   
   0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79},
	/*b*/  {
   
   0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08},
	/*c*/  {
   
   0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a},
	/*d*/  {
   
   0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e},
	/*e*/  {
   
   0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf},
	/*f*/  {
   
   0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}
};

//逆S盒
static unsigned char InvSBox[16][16] = 
{
   
   
				/* 0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f */
	/*0*/  {
   
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值