当前位置:文档之家› (完整版)密码学毕业课程设计-AES加密解密文档

(完整版)密码学毕业课程设计-AES加密解密文档

成都信息工程学院课程设计报告AES加密解密的实现课程名称:应用密码算法程序设计学生姓名:学生学号:专业班级:任课教师:年月日目录1.背景 (1)2.系统设计 (1)2.1系统主要目标 (1)2.2主要软件需求(运行环境) (2)2.3功能模块与系统结构 (2)3 系统功能程序设计 (4)3.1基本要求部分 (4)3.1.1 字节替换 (4)3.1.2行移位 (5)3.1.3列混合 (6)3.1.4密钥加 (6)3.1.5密钥扩展 (7)3.1.6字节替换 (8)3.1.7行移位 (9)3.1.8列混合 (9)3.1.9 加密 (10)3.1.10 解密 (11)4. 测试报告 (12)5.结论 (21)参考文献 (21)1.背景AES,密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。

这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。

经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。

2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

AES 有一个固定的128位的块大小和128,192或256位大小的密钥大小。

该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijndael之命名之,投稿高级加密标准的甄选流程。

(Rijdael的发音近于"Rhine doll"。

)AES在软体及硬件上都能快速地加解密,相对来说较易于实作,且只需要很少的记忆体。

作为一个新的加密标准,目前正被部署应用到更广大的范围.2.系统设计2.1系统主要目标基本要求部分:1.在深入理解AES加密解密算法理论的基础上,设计一个AES加密解密软件系统;2.完成一个明文分组的加解密,明文和密钥是十六进制,长度都为64比特(16个16进制数),输入明文和密钥,输出密文,进行加密后,能够进行正确的解密;3. 程序运行时,要求输出每一轮使用的密钥,以及每一轮加密或解密之后的16进制表示的值;4. 要求提供所设计系统的报告及完整的软件。

较高要求部分:1.如果明文不止一个分组,程序能完成分组,然后加密;最后一个分组长度不足时要求完成填充;密钥长度不足时能进行填充,过长则自动截取前面部分。

2.密钥采用ASCII码,明文要求输入信息可以是文字(可以是汉字或英文,信息量要求不止一个加密分组长度),任意字符,或者是文本文档,或者普通文件。

进行加密后,能够进行正确的解密;3.程序代码有比较好的结构,模块划分合理,如用类进行封装,通过调用类的成员函数实现加密解密功能,函数的参数及返回值设置合理等;4.界面友好,程序实现有新意。

2.2主要软件需求(运行环境)本软件适用VC语言编写,编译成功后的EXE文件可以在装有windows系统的任何计算机上使用。

测试平台:Windows XP Professional使用软件:Visual C++ 6.02.3功能模块与系统结构主要功能模块如下:1.字节替换SubByte2.行移位ShiftRow3.列混合MixColumn4.轮密钥加AddRoundKey5.逆字节替换通过逆S盒的映射变换得到6.逆行移位InvShiftRow与加密时的行移位区别在于移位方向相反。

7.逆列混淆加密与解密系统流程图如下所示,3 系统功能程序设计3.1基本要求部分3.1.1 字节替换SubBytes()变换是一个基于S盒的非线性置换,它用于将输入或中间态的每一个字节通过一个简单的查表操作,将其映射为另一个字节。

映射方法是把输入字节的高四位作为S盒的行值,低四位作为列值,然后取出S盒中对应的行和列的元素作为输出。

unsigned char subbytes(unsigned char state[4][4]){printf("after subbyte:\n"); 取出中间态state映射到S盒中的值赋给中间态statefor(i=0;i<4;i++){for(j=0;j<4;j++)state[i][j]=sbox[state[i][j]]; }for(i=0;i<4;i++) 输出到屏幕显示state{for(j=0;j<4;j++)printf("\t\t%02x ",state[i][j]);printf("\n");}printf("\n");return 0;}3.1.2行移位ShiftRows()完成基于行的循环移位操作,变换方法是第0行不动,第一行循环左移一个字节,第二位循环左移两个字节,第三行循环左移三个字节。

unsigned char shiftrows(unsigned char state[4][4]){printf("after shiftrows:\n"); 在中间态的行上,k=state[1][0]; 第0行不变state[1][0]=state[1][1]; 第一行循环左移一个字节state[1][1]=state[1][2]; 第二行循环左移两个字节state[1][2]=state[1][3]; 第三行循环左移三个字节state[1][3]=k;k=state[2][0];state[2][0]=state[2][2];state[2][2]=k;k=state[2][1];state[2][1]=state[2][3];state[2][3]=k;k=state[3][0];state[3][0]=state[3][3];state[3][3]=state[3][2];state[3][2]=state[3][1];state[3][1]=k;for(i=0;i<4;i++) 输出到屏幕显示state {for(j=0;j<4;j++)printf("\t\t%02x ",state[i][j]);printf("\n");}printf("\n");return 0;}3.1.3列混合MixColumns()实现逐列混合,方法是s’(x)=c(x)*s(x)mod(x^4+1)unsigned char mixcolumns(unsigned char state[4][4]){ printf("after mixcolumns:\n"); 实现(02 03 01 01) 与中间态state分别相乘后异或得相应值for(i=0;i<4;i++) (01 02 03 01){ (01 01 02 03)k=state[0][i]; (03 01 01 02)temp[0] = state[0][i] ^ state[1][i] ^ state[2][i] ^ state[3][i] ;temp[1] = state[0][i] ^ state[1][i] ; temp[1] = xtime(temp[1]); state[0][i] ^= temp[1] ^ temp[0] ;temp[1] = state[1][i] ^ state[2][i] ; temp[1] = xtime(temp[1]); state[1][i] ^= temp[1] ^ temp[0] ;temp[1] = state[2][i] ^ state[3][i] ; temp[1] = xtime(temp[1]); state[2][i] ^= temp[1] ^ temp[0] ;temp[1] = state[3][i] ^ k ; temp[1] = xtime(temp[1]); state[3][i] ^= temp[1] ^ temp[0] ;}for(i=0;i<4;i++) 输出到屏幕显示state {for(j=0;j<4;j++)printf("\t\t%02x ",state[i][j]);printf("\n");}printf("\n");return 0;}3.1.4轮密钥加AddRoundKey()用于将输入或中间态S的每一列与一个密钥字ki进行按位异或,每一个轮密钥由Nb个字组成。

unsigned char addroundkey(unsigned char state[4][4],unsigned char w[4][4]) { printf("addroundkey %d:\n",round++);将中间态state中的每一列与一个密钥字(w[4][4]中的一列)进行按位异或for(i=0;i<4;i++) 完了又赋值给state{for(j=0;j<4;j++)state[i][j]^=w[i][j];}for(i=0;i<4;i++) 输出到屏幕显示出来state{for(j=0;j<4;j++)printf("\t\t%02x ",state[i][j]);printf("\n");}printf("\n");return 0;}3.1.5密钥扩展通过生成器产生Nr+1个轮密钥,每个轮密钥由Nb个字组成,共有Nb(Nr+1)个字。

在加密过程中,需要Nr+1个轮密钥,需要构造4(Nr+1)个32位字。

首先将输入的4个字节直接复制到扩展密钥数组的前4个字中,得到W[0],W[1],W[2],W[3];然后每次用4个字填充扩展密钥数余下的部分。

keyexpandprintf("after keyexpand:\n");for(i=4;i<8;i++){if(i%4==0){ rotword[0]=w[1][i-1];rotword[1]=w[2][i-1];rotword[2]=w[3][i-1];rotword[3]=w[0][i-1];printf("rotword():");for(j=0;j<4;j++) printf("%02x ",rotword[j]);for(j=0;j<4;j++)subword[j]=sbox[rotword[j]];printf("\nsubword():");for(j=0;j<4;j++) printf("%02x ",subword[j]); printf("\n\n");for(j=0;j<4;j++)rcon[j]=subword[j]^ Rcon[N][j] ;printf("after ^Rcon():");for(j=0;j<4;j++) printf("%02x ",rcon[j]); printf("\n\n");for(j=0;j<4;j++)w[j][i%4]=rcon[j]^ w[j][i-4] ;printf("w[%d] :",count);for(j=0;j<4;j++) printf(" %02x ",w[j][i%4]) ;count++;}else{for(j=0;j<4;j++)w[j][i%4]=w[j][i%4]^w[j][(i%4)-1];printf("w[%d] :",count);for(j=0;j<4;j++) printf(" %02x ",w[j][i%4]);count++;}printf("\n\n");}printf("密钥扩展Round key:\n");for(i=0;i<4;i++){for(j=0;j<4;j++) printf("\t\t%02x ",w[i][j]);printf("\n");}printf("\n");3.1.6逆字节替换与字节代替类似,逆字节代替基于逆S盒实现。

相关主题