在移动端需要安全算法时,直接使用开源库可能不合适(开源库都比较大,也可以自己抽取需要的代码),本Demo是根据AES的原理来实现算法,采用ECB/PKCS5Padding,实现短小精悍!!
注意:本算法在生成加密key时,使用了md5算法,编译本demo需要依赖 C++自行实现MD5算法 里面的算法。
#ifndef _AES_20140317_H_ #define _AES_20140317_H_ #define Bits128 16 #define Bits192 24 #define Bits256 32 #define ENCRYPT_BLOCK_SIZE 16 #define SUCESS 0 #define TRUE 1 #include "md5.h" #include <stdio.h> #include <malloc.h> typedef unsigned char _u8; typedef int _int32; typedef unsigned int _u32; typedef struct { _int32 Nb; _int32 Nk; _int32 Nr; _u8 State[4][4]; _u8 key[32]; _u8 w[16 * 15]; } ctx_aes; enum AESKeyLength { AES_KEY_LENGTH_16 = 16, AES_KEY_LENGTH_24 = 24, AES_KEY_LENGTH_32 = 32 }; namespace comm { namespace util { class AES { public: AES(); ~AES() { if (Sbox != NULL) { delete []Sbox; Sbox = NULL; } if (iSbox != NULL) { delete []iSbox; iSbox = NULL; } if (Rcon != NULL) { delete []Rcon; Rcon = NULL; } } public: int decrypt4aes(const std::string &inData, const std::string &strKey, std::string &outData, std::string &errMsg); int encrypt4aes(const std::string &inData, const std::string &strKey, std::string &outData, std::string &errMsg); private: void aes_init(ctx_aes* aes, int keySize, _u8* keyBytes); void aes_cipher(ctx_aes* aes, _u8* input, _u8* output); void aes_invcipher(ctx_aes* aes, _u8* input, _u8* output); void SetNbNkNr(ctx_aes* aes, _int32 keyS); void AddRoundKey(ctx_aes* aes, _int32 round); void SubBytes(ctx_aes* aes); void InvSubBytes(ctx_aes* aes); void ShiftRows(ctx_aes* aes); void InvShiftRows(ctx_aes* aes); void MixColumns(ctx_aes* aes); void InvMixColumns(ctx_aes* aes); _u8 gfmultby01(_u8 b); _u8 gfmultby02(_u8 b); _u8 gfmultby03(_u8 b); unsigned char gfmultby09(unsigned char b); unsigned char gfmultby0b(unsigned char b); unsigned char gfmultby0d(unsigned char b); unsigned char gfmultby0e(unsigned char b); void KeyExpansion(ctx_aes* aes); void SubWord(_u8 *word, _u8 *result); void RotWord(_u8 *word, _u8 *result); _int32 aes_encrypt_with_known_key(char* buffer, _u32* len, _u8 *key,std::string &outData); _int32 aes_decrypt_with_known_key(char* p_data_buff, _u32* p_data_buff_len, _u8 *key,std::string &outData); private: _u8 *Sbox; _u8 *iSbox; _u8 *Rcon; }; } } //comm::util #endif//_AES_20140317_H_
#include "aes.h" using namespace comm::util; AES::AES() { Sbox = new _u8[256]; _u8 Sbox_temp[256] = { 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 }; for (int i = 0; i < 256; i++) { Sbox[i] = Sbox_temp[i]; } iSbox = new _u8[256]; _u8 iSbox_temp[256] = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, /*1*/0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, /*2*/0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, /*3*/0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, /*4*/0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, /*5*/0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, /*6*/0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, /*7*/0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, /*8*/0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, /*9*/0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, /*a*/0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, /*b*/0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, /*c*/0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, /*d*/0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, /*e*/0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, /*f*/0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; for (int i = 0; i < 256; i++) { iSbox[i] = iSbox_temp[i]; } Rcon = new _u8[44]; _u8 Rcon_temp[44] = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00 }; for (int i = 0; i < 44; i++) { Rcon[i] = Rcon_temp[i]; } } void AES::aes_init(ctx_aes* aes, int keySize, _u8* keyBytes) { SetNbNkNr(aes, keySize); memcpy(aes->key, keyBytes, keySize); KeyExpansion(aes); } void AES::aes_cipher(ctx_aes* aes, _u8* input, _u8* output) // encipher 16-bit input { // state = input int i; int round; memset(&aes->State[0][0], 0, 16); for (i = 0; i < (4 * aes->Nb); i++) // { aes->State[i % 4][i / 4] = input[i]; } AddRoundKey(aes, 0); for (round = 1; round <= (aes->Nr - 1); round++) // main round loop { SubBytes(aes); ShiftRows(aes); MixColumns(aes); AddRoundKey(aes, round); } // main round loop SubBytes(aes); ShiftRows(aes); AddRoundKey(aes, aes->Nr); // output = state for (i = 0; i < (4 * aes->Nb); i++) { output[i] = aes->State[i % 4][i / 4]; } } // Cipher() void AES::aes_invcipher(ctx_aes* aes, _u8* input, _u8* output) // decipher 16-bit input { // state = input int i; int round; memset(&aes->State[0][0], 0, 16); for (i = 0; i < (4 * aes->Nb); i++) { aes->State[i % 4][i / 4] = input[i]; } AddRoundKey(aes, aes->Nr); for (round = aes->Nr - 1; round >= 1; round--) // main round loop { InvShiftRows(aes); InvSubBytes(aes); AddRoundKey(aes, round); InvMixColumns(aes); } // end main round loop for InvCipher InvShiftRows(aes); InvSubBytes(aes); AddRoundKey(aes, 0); // output = state for (i = 0; i < (4 * aes->Nb); i++) { output[i] = aes->State[i % 4][i / 4]; } } // InvCipher() void AES::SetNbNkNr(ctx_aes* aes, _int32 keyS) { aes->Nb = 4; // block size always = 4 words = 16 bytes = 128 bits for AES aes->Nk = 4; if (keyS == Bits128) { aes->Nk = 4; // key size = 4 words = 16 bytes = 128 bits aes->Nr = 10; // rounds for algorithm = 10 } else if (keyS == Bits192) { aes->Nk = 6; // 6 words = 24 bytes = 192 bits aes->Nr = 12; } else if (keyS == Bits256) { aes->Nk = 8; // 8 words = 32 bytes = 256 bits aes->Nr = 14; } } // SetNbNkNr() void AES::AddRoundKey(ctx_aes* aes, _int32 round) { int r, c; for (r = 0; r < 4; r++) { for (c = 0; c < 4; c++) { //w: 4*x+y aes->State[r][c] = (unsigned char) ((int) aes->State[r][c] ^ (int) aes->w[4 * ((round * 4) + c) + r]); } } } // AddRoundKey() void AES::SubBytes(ctx_aes* aes) { int r, c; for (r = 0; r < 4; r++) { for (c = 0; c < 4; c++) { aes->State[r][c] = Sbox[16 * (aes->State[r][c] >> 4) + (aes->State[r][c] & 0x0f)]; } } } // SubBytes void AES::InvSubBytes(ctx_aes* aes) { int r, c; for (r = 0; r < 4; r++) { for (c = 0; c < 4; c++) { aes->State[r][c] = iSbox[16 * (aes->State[r][c] >> 4) + (aes->State[r][c] & 0x0f)]; } } } // InvSubBytes void AES::ShiftRows(ctx_aes* aes) { unsigned char temp[4 * 4]; int r, c; for (r = 0; r < 4; r++) // copy State into temp[] { for (c = 0; c < 4; c++) { temp[4 * r + c] = aes->State[r][c]; } } //?? for (r = 1; r < 4; r++) // shift temp into State { for (c = 0; c < 4; c++) { aes->State[r][c] = temp[4 * r + (c + r) % aes->Nb]; } } } // ShiftRows() void AES::InvShiftRows(ctx_aes* aes) { unsigned char temp[4 * 4]; int r, c; for (r = 0; r < 4; r++) // copy State into temp[] { for (c = 0; c < 4; c++) { temp[4 * r + c] = aes->State[r][c]; } } for (r = 1; r < 4; r++) // shift temp into State { for (c = 0; c < 4; c++) { aes->State[r][(c + r) % aes->Nb] = temp[4 * r + c]; } } } // InvShiftRows() void AES::MixColumns(ctx_aes* aes) { unsigned char temp[4 * 4]; int r, c; for (r = 0; r < 4; r++) // copy State into temp[] { for (c = 0; c < 4; c++) { temp[4 * r + c] = aes->State[r][c]; } } for (c = 0; c < 4; c++) { aes->State[0][c] = (unsigned char) ((int) gfmultby02(temp[0 + c]) ^ (int) gfmultby03(temp[4 * 1 + c]) ^ (int) gfmultby01(temp[4 * 2 + c]) ^ (int) gfmultby01(temp[4 * 3 + c])); aes->State[1][c] = (unsigned char) ((int) gfmultby01(temp[0 + c]) ^ (int) gfmultby02(temp[4 * 1 + c]) ^ (int) gfmultby03(temp[4 * 2 + c]) ^ (int) gfmultby01(temp[4 * 3 + c])); aes->State[2][c] = (unsigned char) ((int) gfmultby01(temp[0 + c]) ^ (int) gfmultby01(temp[4 * 1 + c]) ^ (int) gfmultby02(temp[4 * 2 + c]) ^ (int) gfmultby03(temp[4 * 3 + c])); aes->State[3][c] = (unsigned char) ((int) gfmultby03(temp[0 + c]) ^ (int) gfmultby01(temp[4 * 1 + c]) ^ (int) gfmultby01(temp[4 * 2 + c]) ^ (int) gfmultby02(temp[4 * 3 + c])); } } // MixColumns void AES::InvMixColumns(ctx_aes* aes) { unsigned char temp[4 * 4]; int r, c; for (r = 0; r < 4; r++) // copy State into temp[] { for (c = 0; c < 4; c++) { temp[4 * r + c] = aes->State[r][c]; } } for (c = 0; c < 4; c++) { aes->State[0][c] = (unsigned char) ((int) gfmultby0e(temp[c]) ^ (int) gfmultby0b(temp[4 + c]) ^ (int) gfmultby0d(temp[4 * 2 + c]) ^ (int) gfmultby09(temp[4 * 3 + c])); aes->State[1][c] = (unsigned char) ((int) gfmultby09(temp[c]) ^ (int) gfmultby0e(temp[4 + c]) ^ (int) gfmultby0b(temp[4 * 2 + c]) ^ (int) gfmultby0d(temp[4 * 3 + c])); aes->State[2][c] = (unsigned char) ((int) gfmultby0d(temp[c]) ^ (int) gfmultby09(temp[4 + c]) ^ (int) gfmultby0e(temp[4 * 2 + c]) ^ (int) gfmultby0b(temp[4 * 3 + c])); aes->State[3][c] = (unsigned char) ((int) gfmultby0b(temp[c]) ^ (int) gfmultby0d(temp[4 + c]) ^ (int) gfmultby09(temp[4 * 2 + c]) ^ (int) gfmultby0e(temp[4 * 3 + c])); } } // InvMixColumns _u8 AES::gfmultby01(_u8 b) { return b; } _u8 AES::gfmultby02(_u8 b) { if (b < 0x80) return (_u8) (_int32) (b << 1); else return (_u8) ((_int32) (b << 1) ^ (_int32) (0x1b)); } _u8 AES::gfmultby03(_u8 b) { return (_u8) ((_int32) gfmultby02(b) ^ (_int32) b); } unsigned char AES::gfmultby09(unsigned char b) { return (unsigned char) ((int) gfmultby02(gfmultby02(gfmultby02(b))) ^ (int) b); } unsigned char AES::gfmultby0b(unsigned char b) { return (unsigned char) ((int) gfmultby02(gfmultby02(gfmultby02(b))) ^ (int) gfmultby02(b) ^ (int) b); } unsigned char AES::gfmultby0d(unsigned char b) { return (unsigned char) ((int) gfmultby02(gfmultby02(gfmultby02(b))) ^ (int) gfmultby02(gfmultby02(b)) ^ (int) (b)); } unsigned char AES::gfmultby0e(unsigned char b) { return (unsigned char) ((int) gfmultby02(gfmultby02(gfmultby02(b))) ^ (int) gfmultby02(gfmultby02(b)) ^ (int) gfmultby02(b)); } void AES::KeyExpansion(ctx_aes* aes) { int row; _u8 temp[4]; _u8 result[4], result2[4]; memset(aes->w, 0, 16 * 15); for (row = 0; row < aes->Nk; row++) //Nk=4,6,8 { aes->w[4 * row + 0] = aes->key[4 * row]; aes->w[4 * row + 1] = aes->key[4 * row + 1]; aes->w[4 * row + 2] = aes->key[4 * row + 2]; aes->w[4 * row + 3] = aes->key[4 * row + 3]; } for (row = aes->Nk; row < aes->Nb * (aes->Nr + 1); row++) { temp[0] = aes->w[4 * (row - 1) + 0]; temp[1] = aes->w[4 * (row - 1) + 1]; temp[2] = aes->w[4 * (row - 1) + 2]; temp[3] = aes->w[4 * (row - 1) + 3]; if (row % aes->Nk == 0) { RotWord(temp, result); SubWord(result, result2); memcpy(temp, result2, 4); // temp[0] = (unsigned char) ((int) temp[0] ^ (int) Rcon[4 * (row / aes->Nk) + 0]); temp[1] = (unsigned char) ((int) temp[1] ^ (int) Rcon[4 * (row / aes->Nk) + 1]); temp[2] = (unsigned char) ((int) temp[2] ^ (int) Rcon[4 * (row / aes->Nk) + 2]); temp[3] = (unsigned char) ((int) temp[3] ^ (int) Rcon[4 * (row / aes->Nk) + 3]); } else if (aes->Nk > 6 && (row % aes->Nk == 4)) { SubWord(temp, result); memcpy(temp, result, 4); } // w[row] = w[row-Nk] xor temp aes->w[4 * row + 0] = (unsigned char) ((int) aes->w[4 * (row - aes->Nk) + 0] ^ (int) temp[0]); aes->w[4 * row + 1] = (unsigned char) ((int) aes->w[4 * (row - aes->Nk) + 1] ^ (int) temp[1]); aes->w[4 * row + 2] = (unsigned char) ((int) aes->w[4 * (row - aes->Nk) + 2] ^ (int) temp[2]); aes->w[4 * row + 3] = (unsigned char) ((int) aes->w[4 * (row - aes->Nk) + 3] ^ (int) temp[3]); } // for loop } // KeyExpansion() void AES::SubWord(_u8 *word, _u8 *result) { //²»ÒªÕâÑù·µ»Ø£¡ result[0] = Sbox[16 * (word[0] >> 4) + (word[0] & 0x0f)]; result[1] = Sbox[16 * (word[1] >> 4) + (word[1] & 0x0f)]; result[2] = Sbox[16 * (word[2] >> 4) + (word[2] & 0x0f)]; result[3] = Sbox[16 * (word[3] >> 4) + (word[3] & 0x0f)]; } void AES::RotWord(_u8 *word, _u8 *result) { //²»ÒªÕâÑù·µ»Ø result[0] = word[1]; result[1] = word[2]; result[2] = word[3]; result[3] = word[0]; } _int32 AES::aes_encrypt_with_known_key(char* buffer, _u32* len, _u8 *key, std::string &outData) { _int32 ret; char *pOutBuff; _int32 nOutLen; _int32 nBeginOffset; ctx_aes aes; int nInOffset; int nOutOffset; unsigned char inBuff[ENCRYPT_BLOCK_SIZE], ouBuff[ENCRYPT_BLOCK_SIZE]; if (buffer == NULL) { return -1; } pOutBuff = (char*) malloc(*len + 16); if (pOutBuff == NULL) return -1; nOutLen = 0; nBeginOffset = 0; aes_init(&aes, 16, key); nInOffset = nBeginOffset; nOutOffset = 0; memset(inBuff, 0, ENCRYPT_BLOCK_SIZE); memset(ouBuff, 0, ENCRYPT_BLOCK_SIZE); while (TRUE) { if (*len - nInOffset >= ENCRYPT_BLOCK_SIZE) { memcpy(inBuff, buffer + nInOffset, ENCRYPT_BLOCK_SIZE); aes_cipher(&aes, inBuff, ouBuff); memcpy(pOutBuff + nOutOffset, ouBuff, ENCRYPT_BLOCK_SIZE); nInOffset += ENCRYPT_BLOCK_SIZE; nOutOffset += ENCRYPT_BLOCK_SIZE; } else { int nDataLen = *len - nInOffset; int nFillData = ENCRYPT_BLOCK_SIZE - nDataLen; memset(inBuff, nFillData, ENCRYPT_BLOCK_SIZE); memset(ouBuff, 0, ENCRYPT_BLOCK_SIZE); if (nDataLen > 0) { memcpy(inBuff, buffer + nInOffset, nDataLen); aes_cipher(&aes, inBuff, ouBuff); memcpy(pOutBuff + nOutOffset, ouBuff, ENCRYPT_BLOCK_SIZE); nInOffset += nDataLen; nOutOffset += ENCRYPT_BLOCK_SIZE; } else { aes_cipher(&aes, inBuff, ouBuff); memcpy(pOutBuff + nOutOffset, ouBuff, ENCRYPT_BLOCK_SIZE); nOutOffset += ENCRYPT_BLOCK_SIZE; } break; } } nOutLen = nOutOffset; outData = std::string(pOutBuff, nOutLen); free(pOutBuff); if (nOutLen + nBeginOffset > *len + 16) return -1; *len = nOutLen + nBeginOffset; return 0; } _int32 AES::aes_decrypt_with_known_key(char* pDataBuff, _u32* nBuffLen, _u8 *p_aeskey, std::string &outData) { _int32 ret; int nBeginOffset; char *pOutBuff; int nOutLen; ctx_aes aes; int nInOffset; int nOutOffset; unsigned char inBuff[ENCRYPT_BLOCK_SIZE], ouBuff[ENCRYPT_BLOCK_SIZE]; char * out_ptr; if (pDataBuff == NULL) { return -1; } nBeginOffset = 0; if ((*nBuffLen - nBeginOffset) % ENCRYPT_BLOCK_SIZE != 0) { return -2; } pOutBuff = (char*) malloc(*nBuffLen + 16); if (pOutBuff == NULL) return -1; nOutLen = 0; aes_init(&aes, 16, p_aeskey); nInOffset = nBeginOffset; nOutOffset = 0; memset(inBuff, 0, ENCRYPT_BLOCK_SIZE); memset(ouBuff, 0, ENCRYPT_BLOCK_SIZE); while (*nBuffLen - nInOffset > 0) { memcpy(inBuff, pDataBuff + nInOffset, ENCRYPT_BLOCK_SIZE); aes_invcipher(&aes, inBuff, ouBuff); memcpy(pOutBuff + nOutOffset, ouBuff, ENCRYPT_BLOCK_SIZE); nInOffset += ENCRYPT_BLOCK_SIZE; nOutOffset += ENCRYPT_BLOCK_SIZE; } nOutLen = nOutOffset; out_ptr = pOutBuff + nOutLen - 1; if (*out_ptr <= 0 || *out_ptr > ENCRYPT_BLOCK_SIZE) { ret = -3; } else { if (nBeginOffset + nOutLen - *out_ptr < *nBuffLen) { *nBuffLen = nBeginOffset + nOutLen - *out_ptr; ret = 0; } else { ret = -4; } } outData = std::string(pOutBuff,*nBuffLen); free(pOutBuff); return ret; } int AES::encrypt4aes(const std::string &inData, const std::string &strKey, std::string &outData, std::string &errMsg) { outData = ""; errMsg = ""; if (inData.empty() || strKey.empty()) { errMsg = "indata or key is empty!!"; return -1; } unsigned int iKeyLen = strKey.length(); if (iKeyLen != AES_KEY_LENGTH_16 && iKeyLen != AES_KEY_LENGTH_24 && iKeyLen != AES_KEY_LENGTH_32) { errMsg = "aes key invalid!!"; return -2; } char* aes_data = const_cast<char*>(inData.c_str()); unsigned int aes_data_len = (unsigned int) (inData.length()); unsigned char* md5_result_data = (unsigned char*) (const_cast<char*>(strKey.c_str())); outData = ""; int iResult = aes_encrypt_with_known_key(aes_data, &aes_data_len, md5_result_data, outData); if(iResult) { errMsg = "aes_encrypt_with_known_key failed!!"; iResult = -3; } return iResult; } int AES::decrypt4aes(const std::string &inData, const std::string &strKey, std::string &outData, std::string &errMsg) { outData = ""; errMsg = ""; if (inData.empty() || strKey.empty()) { errMsg = "indata or key is empty!!"; return -1; } unsigned int iKeyLen = strKey.length(); if (iKeyLen != AES_KEY_LENGTH_16 && iKeyLen != AES_KEY_LENGTH_24 && iKeyLen != AES_KEY_LENGTH_32) { errMsg = "aes key invalid!!"; return -2; } int iResult = 0; char* aes_data = const_cast<char*>(inData.c_str()); unsigned int aes_data_len = (unsigned int) (inData.length()); unsigned char* md5_result_data = (unsigned char*) (const_cast<char*>(strKey.c_str())); outData = ""; iResult = aes_decrypt_with_known_key(aes_data, &aes_data_len, md5_result_data, outData); if(iResult) { errMsg = "aes_encrypt_with_known_key failed!!"; iResult = -3; } return iResult; } int main(int argc, char**argv) { std::string md5_data = "123456789"; std::string aes_data = ""; comm::util::MD5 md5; std::string strResult = md5.md5(md5_data); comm::util::AES aes; std::string errMsg; std::string outData; aes.encrypt4aes(aes_data, strResult, outData, errMsg); std::string strInput; aes.decrypt4aes(outData, strResult, strInput, errMsg); for (int i = 0; i < strInput.length(); i++) { printf("%c", strInput[i] & 255); } printf("\n"); return 0; }