织梦CMS - 轻松建站从此开始!

罗索

AES代码实现

落鹤生 发布于 2011-10-17 09:13 点击:次 
AES,Advanced Encryption Standard,高级加密标准,是美国政府组织保护敏感的但未经保密的信息的一种特殊的加密算法。以下是其具体实现的代码及示例。
TAG:

AES,Advanced Encryption Standard,高级加密标准,是美国政府组织保护敏感的但未经保密的信息的一种特殊的加密算法。

AES---对称密码新标准
对称密码体制的发展趋势将以分组密码为重点。分组密码算法通常由密钥扩展算法和加密(解密)算法两部分组成。密钥扩展算法将b字节用户 主密钥扩展成r个子密钥。加密算法由一个密码学上的弱函数f与r个子密钥迭代r次组成。混乱和密钥扩散是分组密码算法设计的基本原则。抵御已知明文的差分 和线性攻击,可变长密钥和分组是该体制的设计要点。

AES是美国国家标准技术研究所NIST旨在取代DES的21世纪的加密标准。

AES的基本要求是,采用对称分组密码体制,密钥长度的最少支持为128、192、256,分组长度128位,算法应易于各种硬件和软件实现。1998年 NIST开始AES第一轮分析、测试和征集,共产生了15个候选算法。1999年3月完成了第二轮AES2的分析、测试。预计在2000年8月AES的最 终结果将公布。

在应用方面,尽管DES在安全上是脆弱的,但由于快速DES芯片的大量生产,使得DES仍能暂时继续使用,为提高安全强度,通常使用独立密钥的三级DES。但是DES迟早要被AES代替。流密码体制较之分组密码在理论上成熟且安全,但未被列入下一代加密标准。

#include <stdio.h>
#include <stdlib.h>

#define NULL 0

typedef struct tagAes
{
    unsigned char round_key[15][4][4];
    unsigned char state[2][4][4];
    int rounds;
}TAes;

const int av_aes_size= sizeof(TAes);

static const unsigned char rcon[10] =
{
    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
};

static unsigned char     sbox[256];
static unsigned char inv_sbox[256];
static unsigned int enc_multbl[4][256];
static unsigned int dec_multbl[4][256];

static void addkey(unsigned __int64 dst[2], unsigned __int64 src[2], unsigned __int64 round_key[2])
{
    dst[0] = src[0] ^ round_key[0];
    dst[1] = src[1] ^ round_key[1];
}

static void subshift(unsigned char s0[2][16], int s, unsigned char *box)
{
    unsigned char (*s1)[16] = s0[0] - s;
    unsigned char (*s3)[16] = s0[0] + s;

    s0[0][0] = box[s0[1][ 0]]; s0[0][ 4] = box[s0[1][ 4]]; s0[0][ 8] = box[s0[1][ 8]]; s0[0][12] = box[s0[1][12]];
    s1[0][3] = box[s1[1][ 7]]; s1[0][ 7] = box[s1[1][11]]; s1[0][11] = box[s1[1][15]]; s1[0][15] = box[s1[1][ 3]];
    s0[0][2] = box[s0[1][10]]; s0[0][10] = box[s0[1][ 2]]; s0[0][ 6] = box[s0[1][14]]; s0[0][14] = box[s0[1][ 6]];
    s3[0][1] = box[s3[1][13]]; s3[0][13] = box[s3[1][ 9]]; s3[0][ 9] = box[s3[1][ 5]]; s3[0][ 5] = box[s3[1][ 1]];
}

static int mix_core(unsigned int multbl[4][256], int ptAes, int b, int c, int d)
{
    return multbl[0][ptAes] ^ multbl[1][b] ^ multbl[2][c] ^ multbl[3][d];
}

static void mix(unsigned char state[2][4][4], unsigned int multbl[4][256], int s1, int s3)
{
    ((unsigned int *)(state))[0] = mix_core(multbl, state[1][0][0], state[1][s1 ][1], state[1][2][2], state[1][s3 ][3]);
    ((unsigned int *)(state))[1] = mix_core(multbl, state[1][1][0], state[1][s3-1][1], state[1][3][2], state[1][s1-1][3]);
    ((unsigned int *)(state))[2] = mix_core(multbl, state[1][2][0], state[1][s3 ][1], state[1][0][2], state[1][s1 ][3]);
    ((unsigned int *)(state))[3] = mix_core(multbl, state[1][3][0], state[1][s1-1][1], state[1][1][2], state[1][s3-1][3]);
}

static void crypt(TAes *ptAes, int s, unsigned char *sbox, unsigned int *multbl)
{
    int r = 0;

    for(r = ptAes->rounds-1; r>0; r--)
    {
        mix(ptAes->state, multbl, 3-s, 1+s);
        addkey(ptAes->state[1], ptAes->state[0], ptAes->round_key[r]);
    }

    subshift(ptAes->state[0][0], s, sbox);
}

/*=================================================================================
函数名:aes_crypt
功能:加密/解密缓冲
算法实现:
参数说明:
           [I/O] ptAes 加密/解密句柄
           [O]   dst 输出的内容
           [I]   src 输入内容
           [I]   count 内容长度
           [I]   iv 初始化向量CBC,NULL代表用默认的ECB
           [I]   decrypt 0-加密/1-解密
返回值说明:成功返回TSPS_OK,否则返回错误号
-----------------------------------------------------------------------------------
修改记录:
日期        版本        修改人        走读人        修改记录
=================================================================================*/
void aes_crypt(TAes *ptAes, unsigned char *dst, unsigned char *src, int count, unsigned char *iv, int decrypt)
{
    while(count--)
    {
        addkey(ptAes->state[1], src, ptAes->round_key[ptAes->rounds]);

        if(decrypt)
        {
            crypt(ptAes, 0, inv_sbox, dec_multbl);
            if(iv)
            {
                addkey(ptAes->state[0], ptAes->state[0], iv);
                memcpy(iv, src, 16);
            }

            addkey(dst, ptAes->state[0], ptAes->round_key[0]);
        }
        else
        {
            if(iv)
            {
                addkey(ptAes->state[1], ptAes->state[1], iv);
            }

            crypt(ptAes, 2,     sbox, enc_multbl);
            addkey(dst, ptAes->state[0], ptAes->round_key[0]);

            if(iv)
            {
                memcpy(iv, dst, 16);
            }
        }

        src += 16;
        dst += 16;
    }
}

static void init_multbl2(unsigned char tbl[1024], int c[4], unsigned char *log8, unsigned char *alog8, unsigned char *sbox)
{
    int i = 0, j = 0;

    for(i = 0; i < 1024; i++)
    {
        int x = sbox[i>>2];
        if(x)
        {
            tbl[i]= alog8[ log8[x] + log8[c[i&3]]];
        }
    }

    for(j = 256; j < 1024; j++)
    {
        for(i =0; i < 4; i++)
        {
            tbl[4 * j + i] = tbl[4 * j + ((i - 1) & 3) - 1024];
        }
    }
}

/*=================================================================================
函数名:aes_init
功能:初始化加密/解密句柄
算法实现:
参数说明:
           [I/O] ptAes 加密/解密句柄
           [I]   key 密钥
           [I]   key_bits 密钥长度
           [I]   decrypt 0-加密/1-解密
返回值说明:成功返回TSPS_OK,否则返回错误号
-----------------------------------------------------------------------------------
修改记录:
日期        版本        修改人        走读人        修改记录
=================================================================================*/
int aes_init(TAes *ptAes, const unsigned char *key, int key_bits, int decrypt)
{
    int i = 0, j = 0, t = 0, rconpointer = 0;
    unsigned char tk[8][4];
    int KC = key_bits>>5;
    int rounds = KC + 6;
    unsigned char log8[256];
    unsigned char alog8[512];
    int c1[4] = {0xe, 0x9, 0xd, 0xb};
    int c2[4] = {0x2, 0x1, 0x1, 0x3};
    int temp = 0;

    if(!enc_multbl[0][sizeof(enc_multbl) / sizeof(enc_multbl[0][0]) - 1])
    {
        j = 1;
        for(i = 0; i < 255; i++)
        {
            alog8[i]= alog8[i+255]= j;
            log8[j] = i;
            j ^= j + j;
            if(j > 255)
            {
                j ^= 0x11B;
            }
        }
        for(i = 0; i < 256; i++)
        {
            j = i ? alog8[255 - log8[i]] : 0;
            j ^= (j << 1) ^ (j << 2) ^ (j << 3) ^ (j << 4);
            j = (j ^ (j>>8) ^ 99) & 255;
            inv_sbox[j] = i;
            sbox    [i] = j;
        }
        init_multbl2(dec_multbl[0], c1, log8, alog8, inv_sbox);
        init_multbl2(enc_multbl[0], c2, log8, alog8, sbox);
    }

    if(key_bits != 128 && key_bits !=192 && key_bits != 256)
    {
        return -1;
    }

    ptAes->rounds= rounds;

    memcpy(tk, key, KC * 4);

    for(t= 0; t < (rounds + 1) * 16;)
    {
        memcpy(ptAes->round_key[0][0] + t, tk, KC * 4);

        t += KC * 4;

        for(i = 0; i < 4; i++)
        {
            tk[0][i] ^= sbox[tk[KC - 1][(i + 1) & 3]];
        }

        tk[0][0] ^= rcon[rconpointer++];

        for(j = 1; j < KC; j++)
        {
            if(KC != 8 || j != KC>>1)
            {
                for(i = 0; i < 4; i++)
                {
                    tk[j][i] ^=      tk[j - 1][i];
                }
            }
            else
            {
                for(i = 0; i < 4; i++)
                {
                    tk[j][i] ^= sbox[tk[j - 1][i]];
                }
            }
        }
    }

    if(decrypt)
    {
        for(i = 1; i < rounds; i++)
        {
            unsigned char tmp[3][16];
            memcpy(tmp[2], ptAes->round_key[i][0], 16);
            subshift(tmp[1], 0, sbox);
            mix(tmp, dec_multbl, 1, 3);
            memcpy(ptAes->round_key[i][0], tmp[0], 16);
        }
    }
    else
    {
        for(i = 0; i < (rounds+1) >> 1; i++)
        {
            for(j = 0; j < 16; j++)
            {
                temp = ptAes->round_key[i][0][j];
                ptAes->round_key[i][0][j] = ptAes->round_key[rounds - i][0][j];
                ptAes->round_key[rounds - i][0][j] = temp;
            }
        }
    }

    return 0;
}


int main()
{
    int j;
    TAes ae, ad;
   
    unsigned char pt[16], temp[16], last[16];

    aes_init(&ae, "PI=3.141592654..", 128, 0);
    aes_init(&ad, "PI=3.141592654..", 128, 1);
   
    for(j = 0; j < 16; j++)
    {
        pt[j]= j;
    }

    aes_crypt(&ae, temp, pt, 1, NULL, 0);
    aes_crypt(&ad, last, temp, 1, NULL, 1);

    printf("序号 原始 加密 解密\n", j, pt[j], temp[j], last[j]);
    for(j = 0; j < 16; j++)
    {
        printf("%2d [%02X] [%02X] [%02X]\n", j, pt[j], temp[j], last[j]);
    }
   
    return 0;
}

(zorru)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201110/15143.html]
本文出处:hi.baidu.com/zorru 作者:zorru
顶一下
(1)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容