上机实验报告(四)
实验课程:应用密码学 实验时间:2013年11月12日
任课教师:刘光军
班级:11级信息与计算科学专业1班 姓名:刘静 学号:0202110123 一、实验名称: AES算法的实现二、实验目的: 1、对算法描述可进行充分理解,精确理解算法的各个步骤; 2、完成AES软件算法的详细设计; 3、用C/C++完成算法的设计模块; 4、编制测试代码。 三、实验要求: 1、要求:C和/或C++语言 2、五种模式(ECB、CBC、CFB、OFB和CTR)之一的加解密 3、程序可以输入明文文件,输出密文文件,并进行加解密正确性测试。 四、实验原理及流程图 AES 是一种可用来保护电子数据的新型加密算法。特别是,AES 是可以使用 128、192 和 256 位密钥的迭代式对称密钥块密码,并且可以对 128 位(16 个字节)的数据块进行加密和解密。由块密码返回的加密数据与输入数据具有相同的位数。迭代式密码使用循环结构来针对输入数据反复执行排列和置换运算。基本算法流程图如下所示: 1
五、报告正文(文档,数据,模型,程序,图形) 1、通过分组讨论,进一步学习AES算法的基本加解密流程。基于以上给出的基本流程模块,在下文中给出算法的基本实现步骤(源程序)。最后,通过实例测试程序的正确性。 /**********加密的实现**********/ #include 2 else if(t0==t1) //同一列. { c[0]=book[(s0+1)%5][t0]; c[1]=book[(s1+1)%5][t0]; } else //不同行不同列. { c[0]=book[s0][t1]; c[1]=book[s1][t0]; } printf(\"%c\ //输出已加密的两个字符. printf(\"%c\} /******************************** *对明文加密. *********************************/ void Encrypt() { char m[2]={' '}; //明文数组. char temp,ch; char flag1,flag2; //用来标志上一轮中处理的第二个字母,提高解密精度. int s0,t0,s1,t1,i; //两个字符的位置参数. temp=' '; //初始化为空字符. i=0; //控制变量. flag1=m[1]; //初始化. while((ch=getchar())!='\\n') { if(ch==' ') //如果输入的是空格跳过去. continue; if(ch=='j') //如果输入的是j则当作i处理. ch='i'; m[i++]=ch; //赋入数组. if(temp!=' ') //如果上一步操作中有两个相同的字母. { m[1]=m[0]; m[0]=temp; temp=' '; i=2; //标志变量,不必再输入下一个. } if(i!=2) //数组赋满,则跳过. 3 continue; i=0; if(m[0]==m[1]) //如果两个字母相同,则处理成不相同的. { temp=m[1]; flag2='x'; while(m[1]==m[0]||m[1]==flag1) m[1]=flag2++; } flag1=m[1]; s0=findlocation(m[0],&t0); //列值传递的是地址. s1=findlocation(m[1],&t1); m[0]=' '; out_put(s0,t0,s1,t1); //在密码本中打印密码. } /*不会出现的情况是:temp!=' ' && m[0]!='\\n' */ if(temp!=' '||m[0]!=' ') //此处是为了防止出现什么也没有输入的情况。 { if(m[0]==' '&&temp!=' ') //最后刚好剩余一位. { m[0]=temp; m[1]=flag2='x'; while(m[1]==m[0]||m[1]==flag1) m[1]=flag2++; } if(temp==' '&&m[0]!=' ') //最后剩余一位并且上一轮中有相同的字母. { //m[0]=temp; m[1]=flag2='x'; while(m[1]==m[0]||m[1]==flag1) m[1]=flag2++; } s0=findlocation(m[0],&t0); s1=findlocation(m[1],&t1); out_put(s0,t0,s1,t1); } 4 } /************************* *构造密码本 **************************/ void createbook() { char key; //key密钥 int temp[25]={' '}; //临时数组,记录密钥中出现字母的位置. int t,flag=0; //辅助变量. flag用于定位新出现字母的位置. /************************************* *构造密码本. **************************************/ for(t=0;t<25;t++) //对整型数组赋值. temp[t]=26; while((key=getchar())!='\\n') //此处要极其注意,用换行符表示其结束. { if(key<'j') t=key-'a'; //t表示字母相对于数组的位置. if(key>'j') t=key-'a'-1; if(temp[t]==26) //若未出现过,则记录其位置. temp[t]=flag++; } for(t=0;t<25;t++) //完善字母的顺序,并映射到密码本。 { if(temp[t]==26) //将未出现过的字母按字母表顺序在数组中编号. temp[t]=flag++; if(t+'a'<'j') //按照次序将临时数组中的字母映射到密码本中. book[temp[t]/5][temp[t]%5]=t+'a'; //处理小于i的情况。 else book[temp[t]/5][temp[t]%5]=t+'a'+1; //处理大于j的情况。 } for(t=0;t<25;t++) //打印。 printf(\"%d \ printf(\"\\n\"); for(t=0;t<25;t++) //打印。 5 { printf(\" %c\ if(!((t+1)%5)) printf(\"\\n\"); } } /******************************* *主函数 ********************************/ int main() { createbook(); //构造密码本。 Encrypt(); //进行加密。 printf(\"\\n\"); return 0; } /********************** *解密 *密码本构造函数相同. *部分不同. ***********************/ #include 6 j=5; } return temp; //返回行数。 } /************************* *密码输出函数 **************************/ void out_put(char str[1001]) { char c[2]={' '}; char cip[1001]; int s0,t0,s1,t1; int i,j; i=j=0; while(str[i]!='\\0') { s0=findlocation(str[i++],&t0); s1=findlocation(str[i++],&t1); if(s0==s1) //同一行。 { c[0]=book[s0][(t0+4)%5]; c[1]=book[s0][(t1+4)%5]; } else if(t0==t1) //同一列. { c[0]=book[(s0+4)%5][t0]; c[1]=book[(s1+4)%5][t0]; } else //不同行不同列. { c[0]=book[s0][t1]; c[1]=book[s1][t0]; } cip[j++]=c[0]; cip[j++]=c[1]; } j=strlen(str); i=0; while(i+2 printf(\"%c\ if(cip[i]!=cip[i+2]) i++; else i+=2; } if(i!=j-1) printf(\"%c\ printf(\"%c\\n\ } /******************************** *对密文解密. *********************************/ void Decry() { char str[1001]; gets(str); if(strlen(str)%2==1) { printf(\"密文的个数不能是奇数!\"); return 0; } else out_put(str); } /************************* *构造密码本 **************************/ void createbook() { char key; //key密钥 int temp[25]={' '}; //临时数组,记录密钥中出现字母的位置. int t,flag=0; //辅助变量. flag用于定位新出现字母的位置. /************************************* *构造密码本. **************************************/ for(t=0;t<25;t++) //对整型数组赋值. temp[t]=26; while((key=getchar())!='\\n') //此处要极其注意,用换行符表示其结束. 8 { if(key<'j') t=key-'a'; //t表示字母相对于数组的位置. if(key>'j') t=key-'a'-1; if(temp[t]==26) //若未出现过,则记录其位置. temp[t]=flag++; } for(t=0;t<25;t++) //完善字母的顺序,并映射到密码本。 { if(temp[t]==26) //将未出现过的字母按字母表顺序在数组中编号. temp[t]=flag++; if(t+'a'<'j') //按照次序将临时数组中的字母映射到密码本中. book[temp[t]/5][temp[t]%5]=t+'a'; //处理小于i的情况。 else book[temp[t]/5][temp[t]%5]=t+'a'+1; //处理大于j的情况。 } for(t=0;t<25;t++) //打印。 printf(\"%d \ printf(\"\\n\"); for(t=0;t<25;t++) //打印。 { printf(\" %c\ if(!((t+1)%5)) printf(\"\\n\"); } } /******************************* *主函数 ********************************/ int main() { createbook(); //构造密码本。 Decry(); //进行加密。 printf(\"\\n\"); return 0; } 9 10 因篇幅问题不能全部显示,请点此查看更多更全内容