AES实验报告4_1

时间:2024.4.13

AES实验报告

本次实验分工:

卢上游 C022012023:                 

密钥扩展:keyexpansion(),keyexpansion_Inv()

主程序main()

文件读写FileWrite(),FileRead()

实验报告撰写

罗希 C022012024:     

S盒查找:S(),S_Inv()

                 脱密:DeEncrtpt()

彭年 C022012026:      

字节乘法 byte_mul()

                 加密:Encrypt()

彭泽斌C022012027:   

行移位:LineShift(),LineShift_Inv()

                    列混合:RowMix(),RowMix_Inv()

一、本程序实现过程:

加密:

解密:

二、函数说明:

1int S(int a) / int S_Inv(int a)

查找S盒函数,参数a存储8位的数据的变量,该函数返回值为S[a],S[256]为按顺序存储的S盒。

int S(int a)               // S盒查找

{

    int S[256]= {……………}; 

    return(S[a]);

}

int S_Inv(int a)          // 逆S盒查找

{

    int S_Inv[256]={……………}; 

    return(S_Inv[a]);

}

2int LineShift(int b[16])/ int LineShift_Inv(int b[16])

表示行移位变换函数,数组b[16]存储共128位的数据,每个数组成员存储8位的数据,函数功能将数组内数据的按一定规则进行交换,并返回给b[16];

int LineShift(int b[16])      //行移位

{

    int a[16]={0},i=0;

    for (i=0;i<16;i++)       //赋值给中间量

        a[i]=b[i];

    b[1]=a[5];

    b[2]=a[10];

    b[3]=a[15];

    b[4]=a[4];

    b[5]=a[9];

    b[6]=a[14];

    b[7]=a[3];

    b[8]=a[8];

    b[9]=a[13];

    b[10]=a[2];

    b[11]=a[7];

    b[12]=a[12];

    b[13]=a[1];

    b[14]=a[6];

    b[15]=a[11];

    return 0;

}

int LineShift_Inv(int b[16])    //逆行移位

{

    int a[16]={0},i=0;

    for (i=0;i<16;i++)         //赋值给中间量

        a[i]=b[i];

    b[1]=a[13];

    b[2]=a[10];

    b[3]=a[7];

    b[4]=a[4];

    b[5]=a[1];

    b[6]=a[14];

    b[7]=a[11];

    b[8]=a[8];

    b[9]=a[5];

    b[10]=a[2];

    b[11]=a[15];

    b[12]=a[12];

    b[13]=a[9];

    b[14]=a[6];

    b[15]=a[3];

    return 0;

}

3int byte_mul(int a,int b):

  表示字节乘法函数,参数a,b表示进行字节乘法的两个变量,均存储一个字节的数据,经过查字节乘法表(256*256),然后返回结果即为a与b的字节的乘法结果。字节乘法表由于是对称距阵,因此表中只存储了对角线的左下角的一部分,字节乘法表见附录。

int byte_mul(int a,int b)        //字节乘法

{

    int x[32896]={。。。。。。。}

     int c;

   if(b>a)

       return(x[(b+b*b)/2+a]);

   else

    return (x[(a+a*a)/2+b]);

}

4int RowMix(int m[16])/int RowMix_Inv(int c[16]):

  表列混合函数,数组m[16]/c[16]表示128位的数据,每个数组成员存储8位的数据,函数的功能是将数组内的数据进行距阵相乘之后,将结果按规定次序返回给m[16]。

int RowMix(int m[16])              //列混合

{

    int a[16],i;

    for(i=0;i<4;i++)              //按列与距阵字节相乘

    {

        a[i*4]=byte_mul(2,m[i*4])^byte_mul(3,m[i*4+1])^m[i*4+2]^m[i*4+3];

        a[i*4+1]=byte_mul(2,m[i*4+1])^byte_mul(3,m[i*4+2])^m[i*4]^m[i*4+3];

        a[i*4+2]=byte_mul(2,m[i*4+2])^byte_mul(3,m[i*4+3])^m[i*4]^m[i*4+1];

        a[i*4+3]=byte_mul(2,m[i*4+3])^byte_mul(3,m[i*4])^m[i*4+2]^m[i*4+1];

    }

    for (i=0;i<16;i++)             //返回给m[16]

        m[i]=a[i];

    return 0;

}

int RowMix_Inv(int c[16])       //逆列混合

{

    int a[16],i=0;

    for(i=0;i<4;i++)            //按列与距阵字节相乘

    {

    a[i*4]=byte_mul(0x0e,c[i*4])^byte_mul(0x0b,c[i*4+1])^byte_mul(0x0d,c[i*4+2])^byte_mul(0x09,c[i*4+3]);

    a[i*4+1]=byte_mul(0x09,c[i*4])^byte_mul(0x0e,c[i*4+1])^byte_mul(0x0b,c[i*4+2])^byte_mul(0x0d,c[i*4+3]);

    a[i*4+2]=byte_mul(0x0d,c[i*4])^byte_mul(0x09,c[i*4+1])^byte_mul(0x0e,c[i*4+2])^byte_mul(0x0b,c[i*4+3]);

    a[i*4+3]=byte_mul(0x0b,c[i*4])^byte_mul(0x0d,c[i*4+1])^byte_mul(0x09,c[i*4+2])^byte_mul(0x0e,c[i*4+3]);   

    }

    for (i=0;i<16;i++)          //返回给c[16]

        c[i]=a[i];

    return 0;

}

5unsigned KeyExpansion(unsigned int Key[4])

  表加密密钥生成函数:数组key[4]保存128位的基本密钥,数组中每个成员保存32位的数据,经过密钥扩展算法得到unsigned int W[44], W[44]为全局变量,每个数组成员按顺序保存圈密钥的32位,按顺序每四个数组成员保存一个圈密钥。

unsigned KeyExpansion(unsigned int Key[4])//密钥扩展

{

    unsigned int i=0,a[5]={0},j=0;

    for (i=0;i<4;i++)       //初始第一圈密钥

    {

        W[i]=Key[i];

    }

    for (i=1;i<11;i++)                      //找出w的每个字节

    {

        a[4]=W[i*4-1];         

        a[3]=a[4]&0x000000ff;

        a[2]=(a[4]&0x0000ff00)>>8;

        a[1]=(a[4]&0x00ff0000)>>16;

        a[0]=(a[4]&0xff000000)>>24;

        for (j=0;j<4;j++)                   //对每个字节查询S盒

            a[j]=S(a[j]);

        a[4]=a[0]^(a[1]<<24)^(a[2]<<16)^(a[3]<<8);   //按字节循环左移一位操作,并合成为四个字节的字,a[4]为temp值

        W[i*4]=W[(i-1)*4]^a[4]^Rcon(i);

        W[i*4+1]=W[i*4-3]^W[i*4];

        W[i*4+2]=W[i*4-2]^W[i*4+1];

        W[i*4+3]=W[i*4-1]^W[i*4+2];

    }

    return 0;

}

6unsigned KeyExpansion_Inv()

  表脱密密钥生成函数:在此过程中,利用全局变量W[44],经过逆列混合变换,最终得到脱密密钥,并按顺序保存在W[44]中,每四个数组成员保存一个圈密钥。

unsigned KeyExpansion_Inv()                 //密钥逆扩展

{

    unsigned int i=0,b[16]={0},j=0,temp=0;

    int a[16]={0};

    for(j=1;j<10;j++)

    {

        for (i=0;i<4;i++)                   //取出每个字节

        {

            temp=W[i+j*4];

            W[i+j*4]=0;

            a[3+4*i]=temp&0x000000ff;

            a[2+4*i]=(temp&0x0000ff00)>>8;

            a[1+4*i]=(temp&0x00ff0000)>>16;

            a[4*i]=(temp&0xff000000)>>24;

        }

        RowMix_Inv(a);      //进行列混合变换

        for (i=0;i<4;i++)           //合成为四个字节的字

            W[i+j*4]=a[3+4*i]^(a[2+4*i]<<8)^(a[1+4*i]<<16)^(a[4*i]<<24);

    }

    return 0;

}

7int FileRead(int mingwen[n][16])

  读文件函数:从指定文件中读取全部数据并返回给mingwen[n][16],n通过#define n 3定义,为需加密的数据规模(共n个128bit)。

int FileRead(int mingwen[n][16])

{

    FILE *fp;

    int i=0,j=0;

    char ss[20];     //ss[]为需加、解密的明文或密文指定路径的文件名

    printf("请输入读取数据的文件路径:(如c:jiami.txt)");

    scanf("%s",ss);

    if((fp = fopen(ss, "r+")) == NULL)//文件设置为可读写

        printf("文件打开失败 \n");

    else

        for(j=0;j<n;j++)                      //从文件中读取数据按每段16个字节读取,共n段

            for (i=0;i<16;i++)

            {

                fscanf(fp, "%2x",&mingwen[j][i]);

            }

            fclose(fp);

            return 0;

}

8int FileWrite(int m[16],char ssm[20])

写文件函数,ssm[]为文件名,功能是将数组m[16]中的数据写入到指定文件名中。

int FileWrite(int m[],char ssm[])//ssm[]表示密文保存到指定路径的文件名

{

    FILE *fp;

    int i=0;

    if((fp = fopen(ssm, "a+")) == NULL)//文件可读、写,写入数据时,文件指针移到文件末尾,即在文件末尾添加数据

        printf("文件打开失败 \n");

    else

        for (i=0;i<16;i++)

        {

            if(m[i]<=0xf)

            {

                fprintf(fp,"%x",0);

                fprintf(fp,"%x",m[i]);

            }

            else

                fprintf(fp, "%2x",m[i]);

        }

        fclose(fp);

        return 0;

}

9void Encrypt(int m[16],unsigned int key[4])

数据加密函数:数组m[16]保存着共128bit的需要加密的数据,参数key[4]为基本密钥,经过加密后的数据仍然保存在m[16]中。

void Encrypt(int m[],unsigned int key[])

{

    int i=0,k[11][4][4]={0},j=0,l=0;

    KeyExpansion(key);

    for (i=0;i<11;i++)

    {

        for (j=0;j<4;j++)   //由W存储了4个字节的部分密钥,为了运算方便,把各个字节的密钥按顺序取出

        {

            k[i][j][0]=W[i*4+j]>>24;

            k[i][j][1]=(W[i*4+j]&0x00ff0000)>>16;

            k[i][j][2]=(W[i*4+j]&0x0000ff00)>>8;

            k[i][j][3]=W[i*4+j]&0x000000ff;

        }

    }

    for (i=0;i<10;i++)//十一圈

    {

        for (j=0;j<4;j++)//明文与圈密钥异或之后再查找S盒

            for (l=0;l<4;l++)

            {

                m[j*4+l]=m[j*4+l]^k[i][j][l];

                m[j*4+l]=S(m[j*4+l]);

            }

            LineShift(m);    //行移位变换

            if (i!=9)        //第十圈不需要列混合变换

                RowMix(m);  //列混合变换

            if (i==9)        //与最后一圈密钥相与

            {

                for (j=0;j<4;j++)

                    for (l=0;l<4;l++)

                        m[j*4+l]=m[j*4+l]^k[10][j][l]; 

            }

    } 

}

10void DeEncrtpt(int m[16],unsigned int key[4])

数据解密函数:数组m[16]保存着共128bit的需要解密的数据,数组key[4]为基本密钥,经过加密后数据仍然保存在m[16]中。

void DeEncrtpt(int m[],unsigned int key[])   //脱密算法

{

    int i=0,k[11][4][4]={0},j=0,l=0;

    KeyExpansion(key);    //产生加密密钥

    KeyExpansion_Inv();   //由加密密钥得脱密密钥

    for (i=10;i>=0;i--)   //共十一圈

    {

        for (j=0;j<4;j++)//以字节为单位取出的密钥

        {

            k[10-i][j][0]=W[i*4+j]>>24;

            k[10-i][j][1]=(W[i*4+j]&0x00ff0000)>>16;

            k[10-i][j][2]=(W[i*4+j]&0x0000ff00)>>8;

            k[10-i][j][3]=W[i*4+j]&0x000000ff;

        }

    }

    for (i=0;i<10;i++)

    {

        for (j=0;j<4;j++)       //密文与密钥异或并进行S盒查找

            for (l=0;l<4;l++)

            {

                m[j*4+l]=m[j*4+l]^k[i][j][l];

                m[j*4+l]=S_Inv(m[j*4+l]);

            }

            LineShift_Inv(m);   //逆行变换

            if (i!=9)

                RowMix_Inv(m);  //逆列混合

            if (i==9)          // 最后一圈与密钥异或

            {

                for (j=0;j<4;j++)

                    for (l=0;l<4;l++)

                        m[j*4+l]=m[j*4+l]^k[10][j][l]; 

            }

    } 

}

11int main()

主要是对以上函数的调用及整合,从而实现批量从txt文件中读取数据并进行加密/脱密,并写入到指定的txt文件中。

int main()

{

    clock_t start,end,start_ReadFile,end_ReadFile;

    int select=0;

    int m[16]={0},i=0,mingwen[n][16]={0},j=0;

    unsigned int key[4]={0x2b7e1516,0x28aed2a6,0xabf71588,0x09cf4f3c};

    char ssm[20]={NULL};

    printf("加密请按1,解密请按0\n");

    scanf("%d",&select);

    /*printf("请输入密钥:(范例:2b7e1516,28aed2a6,abf71588,09cf4f3c,)\n");

     for(i=0;i<4;i++)

         scanf("%x,",&key[i]);*/

    start=clock(); //计时开始

    start_ReadFile=clock();

    FileRead(mingwen);                //读取文件中的数据

    end_ReadFile=clock();

    printf("请输入写入数据的文件路径:(如c:jiami.txt)");

    scanf("%s",ssm);

    for(j=0;j<n;j++)               //共n段数据进行加密,每段16个字节

    {

        printf("文件中第%d段数据为:\n",j+1);

        for (i=0;i<16;i++)

        {

            m[i]=mingwen[j][i];    //文件中数据赋值批量 给 m[16]

            printf("%x,",m[i]);

        }

        printf("\n");

        if (select==1)       //加密部分

        {

            Encrypt(m,key);   //加密算法,加密后数据返回给 m[16]

            printf("密文为:");

            for (i=0;i<16;i++)    //打印密文

            {

                printf("%x,",m[i]);

            }

            printf("\n");

        }

        if (select==0)         //解密部分

        {

            DeEncrtpt(m,key);   //解密算法

            printf("脱密后明文为:");

            for (i=0;i<16;i++)

                printf("%x,",m[i]);

            printf("\n");

        }

        FileWrite(m,ssm);    //将加密或解密后的数据分批写入到文件中

    }

    end=clock();                                 //计时结束

    printf("文件读运行时间是:%5.2f\n",difftime(end_ReadFile,start_ReadFile));       //写文件所用时间

    printf("加密或解密+文件读写运行时间是:%5.2f\n",difftime(end,start));       //运行时间输出时间;

}

12unsigned int Rcon(int k)

      输入为k,输出0x02的k-1次方对应的字节。

unsigned int Rcon(int k)

{

    unsigned int rcon=0x01;

    for (int j=0;j<k-1;j++)

        rcon=byte_mul(0x02,rcon);//0x02的k-1次方

    return(rcon<<24);           //向左平移24位并返回

}

三、本程序主要实现及功能

1.     考虑到密钥扩展时W[i]有32位,因此类型定义为unsigned int 。

2.     为方便将W[i]中各个字节提取出来,采用相与并移位的方式按字节提取出密钥;同理,可合并多个字节数据到一个变量中。

3.     本程序采用文件操作,可从txt文件中读取明文或密文,可将密文或明文写入到txt文件中。

4.     本程序可对明文或密文进行批量处理,每次处理128bit。其中n值为处理的规模(n个128bit,本程序中n=3)。

5.     本程序有计时操作,并打印出整个加密或解密过程中所用的时间,由于文件读写操作所花时间较多,因此整个时间花费较大。

备注:为节省操作,基本密钥已经在程序代码中给出:

unsigned int key[4]={0x2b7e1516,0x28aed2a6,0xabf71588,0x09cf4f3c}

四、实验结果截图:

加密:

解密:

txt文件内容:

附录

更多相关推荐:
我做的PHOTOSHOP实验报告参考

实验报告一实验目的与要求掌握Photoshop的各种基本操作技巧并能够灵活使用处理各种文字图像二实验原理工具Photoshop软件中的钢笔工具移动工具缩放工具等命令调整抠出图片大小调整图层位置抠出所需图片将图片...

photoshop图像处理实验报告

云南大学软件学院实验报告序号:31实验老师:**实验名称:图像处理课程名称:数字媒体技术实验学号:***姓名:**一.实验名称:图像处理:二.实验目的:◆认识图像处理的原理并初步使用常用的图像处理工具Photo…

实验报告ps

甘肃政法学院本科学生实验报告姓名景红玉学院计算机科学学院专业计算机科学与技术班级20xx专升本实验课程名称多媒体技术及应用指导教师及职称王云峰开课时间20xx20xx学年一学期甘肃政法学院教务处印制

ps实验报告

一Photoshop的基本操作学号20xx12103姓名王胜楠专业电子信息工程成绩实验目的学习了Photoshop软件的基本工具后能运用软件结合自己的设计理念制作一个综合性作品实验内容要求能从不同图片中选取所需...

photoshop实验报告

景德镇陶瓷学院设计艺术学院实验报告课程名称计算机辅导设计姓名陈泽宇学号20xx10113304专业班级11装潢3班成绩教师魏文卿实验项目名称Photoshop基础知识与基本操作基本功能高级功能高级编辑技巧实验学...

ps实验报告

实验报告理工类20xx至20xx学年度第1学期课程名称图像处理系别班级经济贸易系10电子商务2班学号1004131008姓名章亚建授课教师周艳燕指导教师周艳燕实验项目一奥运五环制作三基色调制同组者填写日期实验日...

photoshop实验报告

景德镇陶瓷学院设计艺术学院实验报告课程名称photoshop姓名韩璐学号20xx10113421专业班级装潢四班成绩教师魏文卿实验项目名称Photoshop基础知识与基本操作基本功能高级功能高级编辑技巧实验学时...

材 料 力 学 实 验 报 告

材料力学实验报告专业班级姓名济南大学土建学院力学实验室20xx年1月试验报告须知一实验报告是实验者最后交出的成果是实验资料的分析总结应严肃认真地完成实验报告认真填好实验目的试验用材料实验用器具等内容二要认真如实...

进程调度实验报告

一实验目的用高级语言编写和调试一个进程调度程序以加深对进程的概念及进程调度算法的理解二实验内容和要求编写并调试一个模拟的进程调度程序采用简单时间片轮转法调度算法对五个进程进行调度每个进程有一个进程控制块PCB表...

计算机基础 实验5-图像处理PhotoshopCS4

大学计算机基础实验报告班级学号姓名实验5图像处理PhotoshopCS4一实验目的掌握图像处理软件PhotoshopCS4的基本操作方法二实验要求1掌握PhotoshopCS4中选框移动文字仿制图章等基本工具的...

photoshop实验报告

实验一中文Photoshop70应用基础1上机内容在制作圆环的过程中主要用到新建命令椭圆选框工具和标尺等2上机目的掌握新建命令和标尺的使用方法学会新建图像和在图像中显示标尺3上机操作1选择文件F新建N命令弹出新...

C++迷宫问题实验报告

数据结构集中上机试验报告学院计算机科学与技术专业计算机科学与技术学号00000000班级6姓名20xx01027题目编制一个求解迷宫通路的程序以一个MN的长方阵表示迷宫0和1分别表示迷宫中的通路和障碍设计一个程...

ps实验报告(31篇)