现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

C++自己实现AES算法

2014-05-22 19:43 工业·编程 ⁄ 共 20670字 ⁄ 字号 暂无评论

在移动端需要安全算法时,直接使用开源库可能不合适(开源库都比较大,也可以自己抽取需要的代码),本Demo是根据AES的原理来实现算法,采用ECB/PKCS5Padding,实现短小精悍!!

注意:本算法在生成加密key时,使用了md5算法,编译本demo需要依赖 C++自行实现MD5算法 里面的算法。

相关阅读

----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; 

给我留言

留言无头像?