高級加密標準(Advanced Encryption Standard,AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣爲全世界所使用。
1.加密的調用方法
bool CGlobalFun::Encryption(const CString &strFilePath)
{
if (!PathFileExists(strFilePath))
{
return false;
}
fstream iniFile;
iniFile.open(strFilePath,ios::binary|ios::in);
iniFile.seekg(0,ios::end);
int length = iniFile.tellg();
iniFile.seekg(0,ios::beg);
unsigned char *buf=new unsigned char [length];
iniFile.read((char*)buf,length);
if (iniFile)
{
unsigned char* sKeyAes=new unsigned char [length+16];
memset(sKeyAes,0,sizeof(sKeyAes));
long nRet = AESEncode((unsigned char*)AES_KEY, buf, length, sKeyAes,length + 16);
if (nRet != -99)
{
CString strFileEncPath;
strFileEncPath = strFilePath + ".enc";
fstream iniEncFile;
iniEncFile.open(strFileEncPath,ios::binary|ios::out);
iniEncFile.write((const char *)sKeyAes,nRet);
iniEncFile.close();
delete sKeyAes;
}
}
iniFile.close();
delete buf;
return true;
}
2.解密的調用方法
bool CGlobalFun::Decryption(const CString &strFilePath)
{
CString strFileEncPath;
strFileEncPath = strFilePath + ".enc";
if (!PathFileExists(strFileEncPath))
{
return false;
}
fstream iniEncFile;
iniEncFile.open(strFileEncPath,ios::binary|ios::in);
iniEncFile.seekg(0,ios::end);
int length = iniEncFile.tellg();
unsigned char *buf=new unsigned char [length];
iniEncFile.seekg(0,ios::beg);
iniEncFile.read((char*)buf,length);
if (iniEncFile)
{
unsigned char* sKeyAes=new unsigned char [length+16];
memset(sKeyAes,0,sizeof(sKeyAes));
long oLen = AESDecode((unsigned char*)AES_KEY, buf, length, sKeyAes,length);
if (oLen != -99)
{
fstream iniFile;
iniFile.open(strFilePath,ios::binary|ios::out);
iniFile.write((const char *)sKeyAes,oLen);
iniFile.close();
delete sKeyAes;
}
}
delete buf;
iniEncFile.close();
return true;
}
Rijndaels.h
/**
* Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit
* block size and 256-bit key-size.
*/
#ifndef _RIJNDAEL_H_
#define _RIJNDAEL_H_
#define KEY_LEN_BYTES 32 // 密鑰256位
#define ROUNDS 14
#define ROUND_KEY_COUNT ((ROUNDS + 1) * 4)
typedef unsigned char BYTE;
typedef BYTE * PBYTE;
long AESEncode(unsigned char * pKey, unsigned char * pIn, long nInLen, unsigned char * pOut,long nOutLen);
long AESDecode(unsigned char * pKey, unsigned char * pIn, long nInLen, unsigned char * pOut,long nOutLen);
int DecodeBase64(unsigned char * btSrc, int iSrcLen, unsigned char * btRet, int * piRetLen);
int EncodeBase64(unsigned char * btSrc, int iSrcLen, unsigned char * btRet, int * piRetLen);
class CRijndael{
public:
CRijndael();
~CRijndael();
public:
static int BLOCK_SIZE;
void Init();
/**
* Set IV in CBC mode.
*
* @param pIV point the 16 bytes IV data.
*/
void setIV(PBYTE pIV);
/**
* Expand a user-supplied key material into a session encryption key.
*
* @param key The 256-bit user-key to use.
*/
void makeKey(PBYTE pKey);
/**
* Encrypt an arbitrary length array.
* @return number of bytes written.
*/
int encrypt(BYTE* in, int inOffset, int inLen,
BYTE* out, int outOffset);
/**
* Decrypt an arbitrary length array.
*/
int decrypt(BYTE* in, int inOffset, int inLen,
BYTE* out, int outOffset);
protected:
/**
* Invert a session encryption key into a session decryption key.
*/
void invertKey(int* K);
/**
* Encrypt exactly one block of plaintext.
*/
void blockEncrypt(BYTE* in, BYTE* out);
void blockEncrypt(BYTE* in, int inOffset,
BYTE* out, int outOffset);
/**
* Decrypt exactly one block of plaintext.
*/
void blockDecrypt(BYTE* in, BYTE* out);
void blockDecrypt(BYTE* in, int inOffset,
BYTE* out, int outOffset);
private:
static bool ROUNDS_12, ROUNDS_14;
static int limit;
BYTE S[256], Si[256];
int T1[256],T2[256],T3[256],T4[256],T5[256],T6[256],T7[256],T8[256];
int U1[256],U2[256],U3[256],U4[256];
BYTE rcon[30];
int m_encKey[ROUND_KEY_COUNT];
int m_decKey[ROUND_KEY_COUNT];
BYTE m_iv[16];
};
#endif //_RIJNDAEL_H_
Rijndaels.cpp
/**
* Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit
* block size and 256-bit key-size.
*/
#include "stdafx.h"
#include "Rijndaels.h"
#include <string.h>
int CRijndael::BLOCK_SIZE = 0x10; // block size in bytes
int CRijndael::limit = 14 * 4; // (ROUNDS-1) * 4
bool CRijndael::ROUNDS_14 = 1;
bool CRijndael::ROUNDS_12 = 1;
CRijndael::CRijndael()
{
Init();
}
CRijndael::~CRijndael()
{
}
void CRijndael::Init()
{
//S-BOX
unsigned char sinput[256]=
{
0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,
0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,
0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,
0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,
0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,
0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,
0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,
0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,
0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,
0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,
0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,
0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16
};
// intialise S-boxes and T-boxes
memcpy(S, sinput, sizeof(S));
int ROOT = 0x11B;
int i, j = 0;
for (i = 0; i < 256; i++)
{
int s, s2, s3, i2, i4, i8, i9, ib, id, ie, t;
s = S[i] & 0xFF;
Si[s] = (BYTE)i;
s2 = s << 1;
if (s2 >= 0x100)
s2 ^= ROOT;
s3 = s2 ^ s;
i2 = i << 1;
if (i2 >= 0x100)
i2 ^= ROOT;
i4 = i2 << 1;
if (i4 >= 0x100)
i4 ^= ROOT;
i8 = i4 << 1;
if (i8 >= 0x100)
i8 ^= ROOT;
i9 = i8 ^ i;
ib = i9 ^ i2;
id = i9 ^ i4;
ie = i8 ^ i4 ^ i2;
T1[i] = t = (s2 << 0x18) | (s << 0x10) | (s << 8) | s3;
T2[i] = ((t >> 8) & 0xFFFFFF) | (t << 0x18);
T3[i] = ((t >> 0x10) & 0xFFFF) | (t << 0x10);
T4[i] = ((t >> 0x18) & 0xFF) | (t << 8);
T5[s] = U1[i] = t = (ie << 0x18) | (i9 << 0x10) | (id << 8) | ib;
T6[s] = U2[i] = ((t >> 8) & 0xFFFFFF) | (t << 0x18);
T7[s] = U3[i] = ((t >> 0x10) & 0xFFFF) | (t << 0x10);
T8[s] = U4[i] = ((t >> 0x18) & 0xFF) | (t << 8);
}
//
// round constants
//
int r = 1;
rcon[0] = 1;
for (i = 1; i < 30; i++)
{
r <<= 1;
if (r >= 0x100)
r ^= ROOT;
rcon[i] = (BYTE)r;
}
// Initialise default IV
memset(m_iv, 0x00, sizeof(m_iv));
}
/**
* Expand a user-supplied key material into a session encryption key.
*
* @param key The 256-bit user-key to use.
* @exception InvalidKeyException If the key is invalid.
*/
void CRijndael::makeKey(PBYTE keyBytes)
{
if (keyBytes == NULL)
return ;
int KC = KEY_LEN_BYTES / 4; // keylen in 32-bit elements
int tk[KEY_LEN_BYTES/4];
int K[ROUND_KEY_COUNT];
int i, j;
int tp1,tp2,tp3,tp4;
// copy user material bytes into temporary ints
for (i = 0, j = 0; i < KC; )
{
tp1=(keyBytes[j++]) << 0x18;
tp2=(keyBytes[j++] & 0xFF) << 0x10 ;
tp3=(keyBytes[j++] & 0xFF) << 8;
tp4=(keyBytes[j++] & 0xFF);
tk[i++] =tp1|tp2|tp3|tp4;
}
// copy values into round key arrays
int t = 0;
for ( ; t < KC; t++)
K[t] = tk[t];
char ts[1000];
strcpy(ts,"");
int tt, rconpointer = 0;
while (t < ROUND_KEY_COUNT)
{
// extrapolate using phi (the round key evolution function)
tt = tk[KC - 1];
tk[0] ^= (S[(BYTE)((tt >> 0x10) & 0xFF)] ) << 0x18 ^
(S[(BYTE)((tt >> 8) & 0xFF)] & 0xFF) << 0x10 ^
(S[(BYTE)((tt) & 0xFF)] & 0xFF) << 8 ^
(S[(BYTE)((tt >> 0x18) & 0xFF)] & 0xFF) ^
(rcon[rconpointer++] ) << 0x18;
if (KC != 8)
{
for (i = 1, j = 0; i < KC; )
tk[i++] ^= tk[j++];
}
else
{
for (i = 1, j = 0; i < KC / 2; )
tk[i++] ^= tk[j++];
tt = tk[KC / 2 - 1];
tk[KC / 2] ^= (S[(BYTE)((tt ) & 0xFF)] & 0xFF) ^
(S[(BYTE)((tt >> 8) & 0xFF)] & 0xFF) << 8 ^
(S[(BYTE)((tt >> 0x10) & 0xFF)] & 0xFF) << 0x10 ^
(S[(BYTE)((tt >> 0x18) & 0xFF)] ) << 0x18;
for (j = KC / 2, i = j + 1; i < KC; )
tk[i++] ^= tk[j++];
}
// copy values into round key arrays
for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++)
K[t] = tk[j];
}
// char ttt[10];
// sprintf(ttt,"%d %d ,",j,i);
// strcat(ts,ttt);
// for(int dd=0;dd<60;dd++)
// {
// sprintf(ttt,"%d,",K[dd]);
// strcat(ts,ttt);
// }
//MessageBox(NULL,ts,"a",MB_OK);
memcpy(m_encKey, K, sizeof(K));
// decryption key
invertKey(K);
memcpy(m_decKey, K, sizeof(K));
}
/**
* Invert a session encryption key into a session decryption key.
*/
void CRijndael::invertKey(int* K)
{
int i=0;
for(i=0; i<ROUND_KEY_COUNT/2-4;i+=4)
{
int jj0 = K[i+0];
int jj1 = K[i+1];
int jj2 = K[i+2];
int jj3 = K[i+3];
K[i+0] = K[ROUND_KEY_COUNT-i-4+0];
K[i+1] = K[ROUND_KEY_COUNT-i-4+1];
K[i+2] = K[ROUND_KEY_COUNT-i-4+2];
K[i+3] = K[ROUND_KEY_COUNT-i-4+3];
K[ROUND_KEY_COUNT-i-4+0] = jj0;
K[ROUND_KEY_COUNT-i-4+1] = jj1;
K[ROUND_KEY_COUNT-i-4+2] = jj2;
K[ROUND_KEY_COUNT-i-4+3] = jj3;
}
for (int r = 4; r < ROUND_KEY_COUNT-4; r++)
{
int tt = K[r];
K[r] = U1[(tt >> 0x18) & 0xFF] ^
U2[(tt >> 0x10) & 0xFF] ^
U3[(tt >> 8) & 0xFF] ^
U4[ tt & 0xFF];
}
int j0 = K[ROUND_KEY_COUNT-4];
int j1 = K[ROUND_KEY_COUNT-3];
int j2 = K[ROUND_KEY_COUNT-2];
int j3 = K[ROUND_KEY_COUNT-1];
for(i=ROUND_KEY_COUNT-1; i>3; i-- )
K[i] = K[i-4];
K[0] = j0;
K[1] = j1;
K[2] = j2;
K[3] = j3;
} // invertKey
/**
* Encrypt exactly one block of plaintext.
*/
void CRijndael::blockEncrypt(BYTE* in, BYTE* out)
{
blockEncrypt(in, 0, out, 0);
}
void CRijndael::blockEncrypt(BYTE* in, int inOffset,
BYTE* out, int outOffset)
{
int* K = &m_encKey[0];
// plaintext to ints + key
int keyOffset = 0;
int tp1,tp2,tp3,tp4;
tp1=(in[inOffset++]) << 0x18 ;
tp2=(in[inOffset++] & 0xFF) << 0x10 ;
tp3=(in[inOffset++] & 0xFF) << 8 ;
tp4=(in[inOffset++] & 0xFF);
int t0= (tp1|tp2|tp3|tp4) ^ K[keyOffset++];
tp1=(in[inOffset++]) << 0x18 ;
tp2=(in[inOffset++] & 0xFF) << 0x10 ;
tp3=(in[inOffset++] & 0xFF) << 8 ;
tp4=(in[inOffset++] & 0xFF);
int t1= (tp1|tp2|tp3|tp4) ^ K[keyOffset++];
tp1=(in[inOffset++]) << 0x18 ;
tp2=(in[inOffset++] & 0xFF) << 0x10 ;
tp3=(in[inOffset++] & 0xFF) << 8 ;
tp4=(in[inOffset++] & 0xFF);
int t2= (tp1|tp2|tp3|tp4) ^ K[keyOffset++];
tp1=(in[inOffset++]) << 0x18 ;
tp2=(in[inOffset++] & 0xFF) << 0x10 ;
tp3=(in[inOffset++] & 0xFF) << 8 ;
tp4=(in[inOffset] & 0xFF);
int t3= (tp1|tp2|tp3|tp4) ^ K[keyOffset++];
// apply round transforms
while( keyOffset < limit )
{
int a0, a1, a2;
a0 = T1[(t0 >> 0x18) & 0xFF] ^
T2[(t1 >> 0x10) & 0xFF] ^
T3[(t2 >> 8) & 0xFF] ^
T4[(t3 ) & 0xFF] ^ K[keyOffset++];
a1 = T1[(t1 >> 0x18) & 0xFF] ^
T2[(t2 >> 0x10) & 0xFF] ^
T3[(t3 >> 8) & 0xFF] ^
T4[(t0 ) & 0xFF] ^ K[keyOffset++];
a2 = T1[(t2 >> 0x18) & 0xFF] ^
T2[(t3 >> 0x10) & 0xFF] ^
T3[(t0 >> 8) & 0xFF] ^
T4[(t1 ) & 0xFF] ^ K[keyOffset++];
t3 = T1[(t3 >> 0x18) & 0xFF] ^
T2[(t0 >> 0x10) & 0xFF] ^
T3[(t1 >> 8) & 0xFF] ^
T4[(t2 ) & 0xFF] ^ K[keyOffset++];
t0 = a0; t1 = a1; t2 = a2;
}
// last round is special
int tt = K[keyOffset++];
out[outOffset++] = (BYTE)(S[(t0 >> 0x18) & 0xFF] ^ ((tt >> 0x18) & 0xFF));
out[outOffset++] = (BYTE)(S[(t1 >> 0x10) & 0xFF] ^ ((tt >> 0x10) & 0xFFFF));
out[outOffset++] = (BYTE)(S[(t2 >> 8) & 0xFF] ^ ((tt >> 8) & 0xFFFFFF));
out[outOffset++] = (BYTE)(S[(t3 ) & 0xFF] ^ (tt ));
tt = K[keyOffset++];
out[outOffset++] = (BYTE)(S[(t1 >> 0x18) & 0xFF] ^ ((tt >> 0x18) & 0xFF));
out[outOffset++] = (BYTE)(S[(t2 >> 0x10) & 0xFF] ^ ((tt >> 0x10) & 0xFFFF));
out[outOffset++] = (BYTE)(S[(t3 >> 8) & 0xFF] ^ ((tt >> 8) & 0xFFFFFF));
out[outOffset++] = (BYTE)(S[(t0 ) & 0xFF] ^ (tt ));
tt = K[keyOffset++];
out[outOffset++] = (BYTE)(S[(t2 >> 0x18) & 0xFF] ^ ((tt >> 0x18) & 0xFF));
out[outOffset++] = (BYTE)(S[(t3 >> 0x10) & 0xFF] ^ ((tt >> 0x10) & 0xFFFF));
out[outOffset++] = (BYTE)(S[(t0 >> 8) & 0xFF] ^ ((tt >> 8) & 0xFFFFFF));
out[outOffset++] = (BYTE)(S[(t1 ) & 0xFF] ^ (tt ));
tt = K[keyOffset++];
out[outOffset++] = (BYTE)(S[(t3 >> 0x18) & 0xFF] ^ ((tt >> 0x18) & 0xFF));
out[outOffset++] = (BYTE)(S[(t0 >> 0x10) & 0xFF] ^ ((tt >> 0x10) & 0xFFFF));
out[outOffset++] = (BYTE)(S[(t1 >> 8) & 0xFF] ^ ((tt >> 8) & 0xFFFFFF));
out[outOffset ] = (BYTE)(S[(t2 ) & 0xFF] ^ (tt ));
}
/**
* Decrypt exactly one block of plaintext.
*/
void CRijndael::blockDecrypt(BYTE* in, BYTE* out)
{
blockDecrypt(in, 0, out, 0);
}
void CRijndael::blockDecrypt(BYTE* in, int inOffset,
BYTE* out, int outOffset)
{
int* K = &m_decKey[0];
int keyOffset = 8;
int t0, t1, t2, t3, a0, a1, a2;
int tp1,tp2,tp3,tp4;
tp1=(in[inOffset++] )<< 0x18 ;
tp2=(in[inOffset++] & 0xFF) << 0x10;
tp3=(in[inOffset++] & 0xFF) << 8 ;
tp4=(in[inOffset++] & 0xFF) ;
t0 = (tp1|tp2|tp3|tp4) ^ K[4];
tp1=(in[inOffset++] )<< 0x18 ;
tp2=(in[inOffset++] & 0xFF) << 0x10;
tp3=(in[inOffset++] & 0xFF) << 8 ;
tp4=(in[inOffset++] & 0xFF) ;
t1 = (tp1|tp2|tp3|tp4) ^ K[5];
tp1=(in[inOffset++] )<< 0x18 ;
tp2=(in[inOffset++] & 0xFF) << 0x10;
tp3=(in[inOffset++] & 0xFF) << 8 ;
tp4=(in[inOffset++] & 0xFF) ;
t2 = (tp1|tp2|tp3|tp4) ^ K[6];
tp1=(in[inOffset++] )<< 0x18 ;
tp2=(in[inOffset++] & 0xFF) << 0x10;
tp3=(in[inOffset++] & 0xFF) << 8 ;
tp4=(in[inOffset] & 0xFF) ;
t3 = (tp1|tp2|tp3|tp4) ^ K[7];
if(ROUNDS_12)
{
a0 = T5[(t0>>0x18) & 0xFF] ^ T6[(t3>>0x10)&0xFF] ^
T7[(t2>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];
a1 = T5[(t1>>0x18) & 0xFF] ^ T6[(t0>>0x10)&0xFF] ^
T7[(t3>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
a2 = T5[(t2>>0x18) & 0xFF] ^ T6[(t1>>0x10)&0xFF] ^
T7[(t0>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
t3 = T5[(t3>>0x18) & 0xFF] ^ T6[(t2>>0x10)&0xFF] ^
T7[(t1>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
t0 = T5[(a0>>0x18) & 0xFF] ^ T6[(t3>>0x10)&0xFF] ^
T7[(a2>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];
t1 = T5[(a1>>0x18) & 0xFF] ^ T6[(a0>>0x10)&0xFF] ^
T7[(t3>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];
t2 = T5[(a2>>0x18) & 0xFF] ^ T6[(a1>>0x10)&0xFF] ^
T7[(a0>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
t3 = T5[(t3>>0x18) & 0xFF] ^ T6[(a2>>0x10)&0xFF] ^
T7[(a1>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];
if(ROUNDS_14)
{
a0 = T5[(t0>>0x18) & 0xFF] ^ T6[(t3>>0x10)&0xFF] ^
T7[(t2>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];
a1 = T5[(t1>>0x18) & 0xFF] ^ T6[(t0>>0x10)&0xFF] ^
T7[(t3>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
a2 = T5[(t2>>0x18) & 0xFF] ^ T6[(t1>>0x10)&0xFF] ^
T7[(t0>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
t3 = T5[(t3>>0x18) & 0xFF] ^ T6[(t2>>0x10)&0xFF] ^
T7[(t1>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
t0 = T5[(a0>>0x18) & 0xFF] ^ T6[(t3>>0x10)&0xFF] ^
T7[(a2>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];
t1 = T5[(a1>>0x18) & 0xFF] ^ T6[(a0>>0x10)&0xFF] ^
T7[(t3>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];
t2 = T5[(a2>>0x18) & 0xFF] ^ T6[(a1>>0x10)&0xFF] ^
T7[(a0>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
t3 = T5[(t3>>0x18) & 0xFF] ^ T6[(a2>>0x10)&0xFF] ^
T7[(a1>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];
}
} // if ROUNDS_12
a0 = T5[(t0>>0x18) & 0xFF] ^ T6[(t3>>0x10)&0xFF] ^
T7[(t2>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];
a1 = T5[(t1>>0x18) & 0xFF] ^ T6[(t0>>0x10)&0xFF] ^
T7[(t3>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
a2 = T5[(t2>>0x18) & 0xFF] ^ T6[(t1>>0x10)&0xFF] ^
T7[(t0>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
t3 = T5[(t3>>0x18) & 0xFF] ^ T6[(t2>>0x10)&0xFF] ^
T7[(t1>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
t0 = T5[(a0>>0x18) & 0xFF] ^ T6[(t3>>0x10)&0xFF] ^
T7[(a2>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];
t1 = T5[(a1>>0x18) & 0xFF] ^ T6[(a0>>0x10)&0xFF] ^
T7[(t3>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];
t2 = T5[(a2>>0x18) & 0xFF] ^ T6[(a1>>0x10)&0xFF] ^
T7[(a0>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
t3 = T5[(t3>>0x18) & 0xFF] ^ T6[(a2>>0x10)&0xFF] ^
T7[(a1>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];
a0 = T5[(t0>>0x18) & 0xFF] ^ T6[(t3>>0x10)&0xFF] ^
T7[(t2>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];
a1 = T5[(t1>>0x18) & 0xFF] ^ T6[(t0>>0x10)&0xFF] ^
T7[(t3>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
a2 = T5[(t2>>0x18) & 0xFF] ^ T6[(t1>>0x10)&0xFF] ^
T7[(t0>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
t3 = T5[(t3>>0x18) & 0xFF] ^ T6[(t2>>0x10)&0xFF] ^
T7[(t1>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
t0 = T5[(a0>>0x18) & 0xFF] ^ T6[(t3>>0x10)&0xFF] ^
T7[(a2>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];
t1 = T5[(a1>>0x18) & 0xFF] ^ T6[(a0>>0x10)&0xFF] ^
T7[(t3>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];
t2 = T5[(a2>>0x18) & 0xFF] ^ T6[(a1>>0x10)&0xFF] ^
T7[(a0>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
t3 = T5[(t3>>0x18) & 0xFF] ^ T6[(a2>>0x10)&0xFF] ^
T7[(a1>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];
a0 = T5[(t0>>0x18) & 0xFF] ^ T6[(t3>>0x10)&0xFF] ^
T7[(t2>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];
a1 = T5[(t1>>0x18) & 0xFF] ^ T6[(t0>>0x10)&0xFF] ^
T7[(t3>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
a2 = T5[(t2>>0x18) & 0xFF] ^ T6[(t1>>0x10)&0xFF] ^
T7[(t0>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
t3 = T5[(t3>>0x18) & 0xFF] ^ T6[(t2>>0x10)&0xFF] ^
T7[(t1>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
t0 = T5[(a0>>0x18) & 0xFF] ^ T6[(t3>>0x10)&0xFF] ^
T7[(a2>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];
t1 = T5[(a1>>0x18) & 0xFF] ^ T6[(a0>>0x10)&0xFF] ^
T7[(t3>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];
t2 = T5[(a2>>0x18) & 0xFF] ^ T6[(a1>>0x10)&0xFF] ^
T7[(a0>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
t3 = T5[(t3>>0x18) & 0xFF] ^ T6[(a2>>0x10)&0xFF] ^
T7[(a1>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];
a0 = T5[(t0>>0x18) & 0xFF] ^ T6[(t3>>0x10)&0xFF] ^
T7[(t2>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];
a1 = T5[(t1>>0x18) & 0xFF] ^ T6[(t0>>0x10)&0xFF] ^
T7[(t3>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
a2 = T5[(t2>>0x18) & 0xFF] ^ T6[(t1>>0x10)&0xFF] ^
T7[(t0>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
t3 = T5[(t3>>0x18) & 0xFF] ^ T6[(t2>>0x10)&0xFF] ^
T7[(t1>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
t0 = T5[(a0>>0x18) & 0xFF] ^ T6[(t3>>0x10)&0xFF] ^
T7[(a2>> 8)&0xFF] ^ T8[(a1 )&0xFF] ^ K[keyOffset++];
t1 = T5[(a1>>0x18) & 0xFF] ^ T6[(a0>>0x10)&0xFF] ^
T7[(t3>> 8)&0xFF] ^ T8[(a2 )&0xFF] ^ K[keyOffset++];
t2 = T5[(a2>>0x18) & 0xFF] ^ T6[(a1>>0x10)&0xFF] ^
T7[(a0>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
t3 = T5[(t3>>0x18) & 0xFF] ^ T6[(a2>>0x10)&0xFF] ^
T7[(a1>> 8)&0xFF] ^ T8[(a0 )&0xFF] ^ K[keyOffset++];
a0 = T5[(t0>>0x18) & 0xFF] ^ T6[(t3>>0x10)&0xFF] ^
T7[(t2>> 8)&0xFF] ^ T8[(t1 )&0xFF] ^ K[keyOffset++];
a1 = T5[(t1>>0x18) & 0xFF] ^ T6[(t0>>0x10)&0xFF] ^
T7[(t3>> 8)&0xFF] ^ T8[(t2 )&0xFF] ^ K[keyOffset++];
a2 = T5[(t2>>0x18) & 0xFF] ^ T6[(t1>>0x10)&0xFF] ^
T7[(t0>> 8)&0xFF] ^ T8[(t3 )&0xFF] ^ K[keyOffset++];
t3 = T5[(t3>>0x18) & 0xFF] ^ T6[(t2>>0x10)&0xFF] ^
T7[(t1>> 8)&0xFF] ^ T8[(t0 )&0xFF] ^ K[keyOffset++];
t1 = K[0];
out[outOffset++] = (BYTE)(Si[(a0 >> 0x18) & 0xFF] ^ ((t1 >> 0x18) & 0xFF));
out[outOffset++] = (BYTE)(Si[(t3 >> 0x10) & 0xFF] ^ ((t1 >> 0x10) & 0xFFFF));
out[outOffset++] = (BYTE)(Si[(a2 >> 8) & 0xFF] ^ ((t1 >> 8) & 0xFFFFFF));
out[outOffset++] = (BYTE)(Si[(a1 ) & 0xFF] ^ (t1 ));
t1 = K[1];
out[outOffset++] = (BYTE)(Si[(a1 >> 0x18) & 0xFF] ^ ((t1 >> 0x18) & 0xFF));
out[outOffset++] = (BYTE)(Si[(a0 >> 0x10) & 0xFF] ^ ((t1 >> 0x10) & 0xFFFF));
out[outOffset++] = (BYTE)(Si[(t3 >> 8) & 0xFF] ^ ((t1 >> 8) & 0xFFFFFF));
out[outOffset++] = (BYTE)(Si[(a2 ) & 0xFF] ^ (t1 ));
t1 = K[2];
out[outOffset++] = (BYTE)(Si[(a2 >> 0x18) & 0xFF] ^ ((t1 >> 0x18) & 0xFF));
out[outOffset++] = (BYTE)(Si[(a1 >> 0x10) & 0xFF] ^ ((t1 >> 0x10) & 0xFFFF));
out[outOffset++] = (BYTE)(Si[(a0 >> 8) & 0xFF] ^ ((t1 >> 8) & 0xFFFFFF));
out[outOffset++] = (BYTE)(Si[(t3 ) & 0xFF] ^ (t1 ));
t1 = K[3];
out[outOffset++] = (BYTE)(Si[(t3 >> 0x18) & 0xFF] ^ ((t1 >> 0x18) & 0xFF));
out[outOffset++] = (BYTE)(Si[(a2 >> 0x10) & 0xFF] ^ ((t1 >> 0x10) & 0xFFFF));
out[outOffset++] = (BYTE)(Si[(a1 >> 8) & 0xFF] ^ ((t1 >> 8) & 0xFFFFFF));
out[outOffset ] = (BYTE)(Si[(a0 ) & 0xFF] ^ (t1 ));
}
/**
* Encrypt an arbitrary length array.
* @return number of bytes written.
*/
int CRijndael::encrypt(BYTE* in, int inOffset, int inLen,
BYTE* out, int outOffset) {
//int size = inLen;
int written = 0;
while (inLen > 0)
{
memset(m_iv, 0x00, sizeof(m_iv));
for(int i = 0; i < BLOCK_SIZE; i++)
m_iv[i] ^= in[inOffset+i];
blockEncrypt(m_iv, 0, out, outOffset);
memcpy(m_iv, out+outOffset, BLOCK_SIZE);
inOffset += BLOCK_SIZE;
outOffset += BLOCK_SIZE;
inLen -= BLOCK_SIZE;
written += BLOCK_SIZE;
}
return written;
}
/**
* Decrypt an arbitrary length array.
*/
int CRijndael::decrypt(BYTE* in, int inOffset, int inLen,
BYTE* out, int outOffset) {
//int size = inLen;
int written = 0;
while (inLen > 0)
{
blockDecrypt(in, inOffset, out, outOffset);
memset(m_iv, 0x00, sizeof(m_iv));
for(int i = 0; i < BLOCK_SIZE; i++)
out[outOffset+i] ^= m_iv[i];
memcpy(m_iv, in+inOffset, BLOCK_SIZE);
inOffset += BLOCK_SIZE;
outOffset += BLOCK_SIZE;
inLen -= BLOCK_SIZE;
written += BLOCK_SIZE;
}
return written;
}
void CRijndael::setIV(PBYTE pIV)
{
memcpy(m_iv, pIV, sizeof(m_iv));
}
long AESEncode(unsigned char * pKey, unsigned char * pIn, long nInLen, unsigned char * pOut,long nOutLen)
{
try
{
//長度控制
if (nOutLen!=nInLen+16)
{
return -99;
}
//取待加密數據除以16後的餘數,得到16-餘數的值
CRijndael cipher;
cipher.makeKey(pKey);
BYTE bPad = (BYTE)(CRijndael::BLOCK_SIZE - nInLen%CRijndael::BLOCK_SIZE);
//將待加密數據中16整數倍的數據先加密(爲了減少內存操作,不將數據合併後再加密)
nOutLen = cipher.encrypt(pIn, 0, nInLen - (nInLen%CRijndael::BLOCK_SIZE), pOut, 0);
//生成填充數據
BYTE* pPad = new BYTE[CRijndael::BLOCK_SIZE];
memcpy(pPad, pIn+nOutLen, nInLen - nOutLen);
memset(pPad+nInLen - nOutLen, bPad, bPad);
//加密填充數據
nOutLen += cipher.encrypt(pPad, 0, CRijndael::BLOCK_SIZE, pOut, nOutLen);
delete pPad;
//返回加密後數據長度
return nOutLen;
}
catch(...)
{
return -99;
}
}
long AESDecode(unsigned char * pKey, unsigned char * pIn, long nInLen, unsigned char * pOut,long nOutLen)
{
try
{
//長度控制
if (nOutLen!=nInLen)
{
return -99;
}
if(nInLen % CRijndael::BLOCK_SIZE != 0)
{
return -99;
}
//創建密鑰對象
CRijndael cipher;
cipher.makeKey(pKey);
//解密數據
BYTE* pBuf = new BYTE[nInLen];
long nOutLen = cipher.decrypt(pIn, 0, nInLen, pBuf, 0);
//安全檢查
if(nOutLen != nInLen)
{
return -99;
}
//安全檢查,填充數據是否正確
BYTE bPad = pBuf[nOutLen-1];
if(CRijndael::BLOCK_SIZE < bPad)
{
delete pBuf;
return -99;
}
for(int i = 0; i < bPad; i++)
{
if(pBuf[nOutLen - 1 - i] != bPad)
{
delete pBuf;
return -99;
}
}
//保存解密後數據
nOutLen -= bPad;
memcpy(pOut, pBuf, nOutLen);
delete pBuf;
//返回解密後數據長度
return nOutLen;
}
catch(...)
{
return -99;
}
}
char D2HC(int dec)
{
if (dec>=0 && dec<=9)
return dec+'0';
return dec-10+'A';
}
void B2HS(BYTE *bin,char *hex,int len)
{
int i;
for (i=0;i<len;i++) {
hex[i*2]=D2HC(bin[i]>>4);
hex[i*2+1]=D2HC(bin[i]&0x0F);
}
}
/*====================================================================
Base64編碼函數
btSrc指向被編碼的數據緩衝區
iSrcLen被編碼的數據的大小(字節)
btRet指向存放Base64編碼的數據緩衝區
piRetLen指向存放Base64編碼的數據緩衝區的長度
若btRet爲NULL函數返回0,piRetLen傳回btSrc的Base64編碼所需緩衝區的大小
若btRet指向的緩衝區太小,函數返回-1
否則函數返回實際btSrc的Base64編碼所需緩衝區的大小
=====================================================================*/
int EncodeBase64(unsigned char * btSrc, int iSrcLen, unsigned char * btRet, int * piRetLen) //Base64編碼
{
int i = 0, j = 0, k = 0 ;
BYTE EncodeBase64Map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
i = (iSrcLen+2) / 3 * 4 ; //獲取btSrc的Base64編碼所需緩衝區的大小
if(btRet != NULL)
{
if(*piRetLen < i) //Base64編碼所需緩衝區偏小
return -1 ;
*piRetLen = i ; //*piRetLen返回btSrc的Base64編碼的緩衝區大小
}
else
{
*piRetLen = i ;
return 0 ;
}
k = iSrcLen - iSrcLen % 3 ;
for(i=j=0; i<k; i+=3) //編碼
{
btRet[j++] = EncodeBase64Map[(btSrc[i]>>2)&0x3F] ;
if (j >= *piRetLen )
break;
btRet[j++] = EncodeBase64Map[((btSrc[i]<<4) + (btSrc[i+1]>>4))&0x3F] ;
if (j >= *piRetLen )
break;
btRet[j++] = EncodeBase64Map[((btSrc[i+1]<<2) + (btSrc[i+2]>>6))&0x3F] ;
if (j >= *piRetLen )
break;
btRet[j++] = EncodeBase64Map[btSrc[i+2]&0x3F] ;
if (j >= *piRetLen )
break;
}
k = iSrcLen - k ;
if(1 == k)
{
btRet[j++] = EncodeBase64Map[(btSrc[i]>>2)&0x3F] ;
if (j >= *piRetLen )
return ++j;
btRet[j++] = EncodeBase64Map[(btSrc[i]<<4)&0x3F] ;
if (j >= *piRetLen )
return ++j;
btRet[j++] = '=' ;
btRet[j++] = '=' ;
if (j >= *piRetLen )
return ++j;
}
else if(2 == k)
{
btRet[j++] = EncodeBase64Map[(btSrc[i]>>2)&0x3F] ;
if (j >= *piRetLen )
return ++j;
btRet[j++] = EncodeBase64Map[((btSrc[i]<<4) + (btSrc[i+1]>>4))&0x3F] ;
if (j >= *piRetLen )
return ++j;
btRet[j++] = EncodeBase64Map[(btSrc[i+1]<<2)&0x3F] ;
if (j >= *piRetLen )
return ++j;
btRet[j] = '=' ;
if (j >= *piRetLen )
return ++j;
}
return ++j ;
}
/*====================================================================
Base64解碼函數
btSrc指向被解碼的數據緩衝區
iSrcLen被解碼的數據的大小(字節)
btRet指向存放Base64解碼的數據緩衝區
piRetLen指向存放Base64解碼的數據緩衝區的長度
若btRet爲NULL函數返回0,piRetLen傳回btSrc的Base64解碼所需緩衝區的大小
若btRet指向的緩衝區太小,函數返回-1
否則函數返回btSrc的Base64解碼所需緩衝區的大小
=====================================================================*/
int DecodeBase64(unsigned char * btSrc, int iSrcLen, unsigned char * btRet, int * piRetLen) //Base64解碼
{
int i = 0, j = 0 ;
BYTE EncodeBase64Map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
BYTE DecodeBase64Map[256] = {0} ;
for(j = iSrcLen; j>0 && '='==btSrc[j-1]; --j) ; //忽略=號
i = (j/4)*3+(j%4+1)/2; //計算解碼後 字符串的長度
if(btRet != NULL)
{
if(*piRetLen < i) //Base64解碼所需緩衝區偏小
return -1 ;
*piRetLen = i ; //*piRetLen返回btSrc的Base64解碼的緩衝區大小
}
else
{
*piRetLen = i ;
return 0 ;
}
j = sizeof(EncodeBase64Map) ;
for(i=0; i<j; ++i)
DecodeBase64Map[ EncodeBase64Map[i] ] = i ;
for(i=j=0; i<iSrcLen; i+=4)
{
btRet[j++] = DecodeBase64Map[btSrc[i ]] << 2 | DecodeBase64Map[btSrc[i+1]] >> 4 ;
if (j >= *piRetLen )
break;
btRet[j++] = DecodeBase64Map[btSrc[i+1]] << 4 | DecodeBase64Map[btSrc[i+2]] >> 2 ;
if (j >= *piRetLen )
break;
btRet[j++] = DecodeBase64Map[btSrc[i+2]] << 6 | DecodeBase64Map[btSrc[i+3]] ;
if (j >= *piRetLen )
break;
}
return *piRetLen ;
}