高级加密标准(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; }
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; }
/** * 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_
/** * 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 ; }