《AES密码学课程设计(C语言实现).docx》由会员分享,可在线阅读,更多相关《AES密码学课程设计(C语言实现).docx(24页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、成都信息工程学院课程设计报告AES加密解密软件的实现 课程名称:应用密码算法程序设计学生姓名: 樊 培 学生学号: 专业班级: 信息对抗技术101 任课教师: 陈 俊 2012 年 6月 7日课程设计成绩评价表指导老师评阅成绩表学习与工作态度(30%)选题意义(10%)文献综述(10%)研究水平与设计能力(20%)课程设计说明说(论文)撰写质量(20%)设计创新(10%)总分指导老师签名: 年 月 日课程设计答辩记录及评价表学生讲述情况教师主要提问记录学生回答问题情况答辩评分评分项目分值评价参考标准评分总分优良中及格差选题意义1098764文献综述1098764研究水平与设计能力2019171
2、51310课程设计说明书(论文)撰写质量201917151310设计创新1098764答辩效果302825221915答辩小组成员签名答辩小组组长签名: 年 月 日课程设计成绩评定表成绩汇总评分项目评分比例分数课程设计总分指导老师评分50%答辩小组评分50%目录1、选题背景42、设计的目标42.1基本目标:42.2较高目标:53、功能需求分析54、模块划分64.1、密钥调度64.2、加密84.2.1、字节代替(SubBytes)84.2.2、行移位(ShiftRows)104.2.3、列混合(MixColumn)114.2.4、轮密钥加(AddRoundKey)134.2.5、加密主函数144
3、.3、解密164.3.1、逆字节替代(InvSubBytes)164.3.2、逆行移位(InvShiftRows)174.3.3、逆列混合(InvMixCloumns)174.3.4、轮密钥加(AddRoundKey)184.3.5、解密主函数185.测试报告205.1主界面205.2测试键盘输入明文和密钥加密205.3测试键盘输入密文和密钥加密215.3测试文件输入明文和密钥加密225.4测试文件输入密文和密钥加密225.5软件说明236.课程设计报告总结237.参考文献241、选题背景高级加密标准(Advanced Encryption Standard,AES),在密码学中又称Rijnd
4、ael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijndael之命名之,投稿高级加密标准的甄选流程。(Rijndael的发音近于 Rhine doll) 严格地说,AES和Rijndael加密法并
5、不完全一样(虽然在实际应用中二者可以互换),因为Rijndael加密法可以支援更大范围的区块和密钥长度:AES的区块长度固定为128 位元,密钥长度则可以是128,192或256位元;而Rijndael使用的密钥和区块长度可以是32位元的整数倍,以128位元为下限,256位元为上限。加密过程中使用的密钥是由Rijndael密钥生成方案产生。大多数AES计算是在一个特别的有限域完成的。 截至2006年,针对AES唯一的成功攻击是旁道攻击 旁道攻击不攻击密码本身,而是攻击那些实作于不安全系统(会在不经意间泄漏资讯)上的加密系统。2005年4月,D.J. Bernstein公布了一种缓存时序攻击法,
6、他以此破解了一个装载OpenSSL AES加密系统的客户服务器6。为了设计使该服务器公布所有的时序资讯,攻击算法使用了2亿多条筛选过的明码。有人认为谁?,对于需要多个跳跃的国际互联网而言,这样的攻击方法并不实用7。 Bruce Schneier称此攻击为“好的时序攻击法”8。 2005年10月,Eran Tromer和另外两个研究员发表了一篇论文,展示了数种针对AES的缓存时序攻击法。其中一种攻击法只需要800个写入动作,费时65毫秒,就能得到一把完整的AES密钥。但攻击者必须在执行加密的系统上拥有执行程式的权限,方能以此法破解该密码系统。虽然高级加密标准也有不足的一面,但是,它仍是一个相对新
7、的协议。因此,安全研究人员还没有那么多的时间对这种加密方法进行破解试验。我们可能会随时发现一种全新的攻击手段会攻破这种高级加密标准。至少在理论上存在这种可能性。2、设计的目标2.1基本目标:(1)在深入理解AES加密/解密算法理论的基础上,能够设计一个AES加密/解密软件系统,采用控制台模式,使用VS2010进行开发,所用语言为C语言进行编程,实现加密解密;(2)能够完成只有一个明文分组的加解密,明文和密钥是ASCII码,长度都为16个字符(也就是固定明文和密钥为128比特),输入明文和密钥,输出密文,进行加密后,能够进行正确的解密;(3)程序运行时,能够按照要求输出最后两轮的轮密钥,以及最后
8、两轮加密或解密之后的值,16进制表示;(4)程序有良好的人机交互操作;(5)能够实现从两个文件分别读取明文和密钥,并在程序中输出明文及密钥;(6)要求有与标准fips-197进行比较的独立模块;(7)最后提供所设计系统的报告及完整的软件,关键代码等。2.2较高目标:能完成以下全部或部分功能:(1)如果从文件读取的明文不止一个分组,程序能完成分组,然后加密;最后一个分组长度不足时要求完成填充;输入信息可以是文本文档,或者普通文件。进行加密后,能够进行正确的解密;(2)密钥包括128bit、192bit、256bit三种情况,有三种情况时与标准fips-197进行比较的独立模块,且从文本文件读取。
9、(3)程序代码有比较好的结构,模块划分合理,如用类进行封装,通过调用类的成员函数实现加密解密功能,函数的参数及返回值设置合理等;(4)对加密大文件的考虑;(5)多线程的使用;(6)界面友好,程序设计实现有创新。 3、功能需求分析AES中的操作均是以字节作为基础的,用到的变量也都是以字节为基础。State可以用44的矩阵表示。AES算法结构对加密和解密的操作,算法由轮密钥开始,并用Nr表示对一个数据分组加密的轮数(加密轮数与密钥长度的关系如表2所示)。AES算法的主循环State矩阵执行轮迭代运算,每轮都包括所有 4个阶段的代换,分别是在规范中被称为 SubBytes(字节替换)、ShiftRo
10、ws(行位移变换)、MixColumns(列混合变换) 和AddRoundKey,(由于外部输入的加密密钥K长度有限 ,所以在算法中要用一个密钥扩展程序(Keyexpansion)把外部密钥 K 扩展成更长的比特串,以生成各轮的加密和解密密钥。)最后执行只包括 3个阶段 (省略 MixColumns变换)的最后一轮运算。表2 AES参数密钥长度(bits)128192256明文分组长度(bits)128128128轮数101214每轮密钥长度(bits)128128128扩展密钥长度(bytes)176206240基本要求按标准分组,以128比特为分组大小。所以轮数为10轮,密钥长度也为128
11、比特4、模块划分划分为三个部分,密钥调度,加密,解密, 4.1、密钥调度一密钥调度包括两个部分:密钥扩展和轮密钥选取。密钥扩展的作用是在数据加密/解密前得到轮变换中中使用的轮密钥,其基本原则是:1) 轮密钥的密钥长度为分组长乘以(1 +Nr),如果分组长为128bit,轮数为了10,则轮密钥的长度为128*(10+1)= 1408bit;2) 种子密钥扩展为扩展密钥,种子密钥长度为4*NK个字节;3) 轮密钥由以下方法从扩展密钥中获得:对第1轮密钥由前Nb个字构成;第2轮密钥由第二个Nb个字节即第Nb + 1个字到第2Nb个字构成;以下依次类推。扩展密钥用数组w(Nb*(Nr + 1)表示,前
12、Nk个字是原密钥,其它密钥字通过计算方法生成。子字节变换是一个返回4个字节的函数,每个字节都是它输入字中相应位置字节通过S盒作用后的结果。循环左移变换返回的是这4个字节经循环置换后的字,即将该字循环左移一个字节,如输入字为w = (a0,a1,a2,a3),则变换后输出字为w = (a1,a2,a3,a0)。扩展密钥的前Nk个字由种子密钥构成,随后的字wi等于字wi-1经一些变换后得到的字temp和字Wi-Nk异或而成;而且对位置为Nk倍数的字变换中不仅运用了循环左移变换和子字节变换,还运用了轮常数Rcon对变换后的字temp进行异或。对轮常数的定义为:Rconi = (Rci,00,00,0
13、0)而Rci表示在有限域GF(28)中xi-1的值,即:Rci = 1 (即01)Rci=x(Rci-1) = xi-1二关键代码/先将密钥数组的元素值存储在3维数组中,然后对其扩展,扩展方式氛围两种,条件是Ki是否是4的倍数,两种密钥方式不同,复杂的是当为4的倍数时,要进行生成Ti-1,先是行移位,然后是进入S盒字节替代,最后与轮常数异或得到,再将此T与Ki-4异或void KeyExpansion(unsigned char *Key,unsigned charExpandKey44) unsigned char RC = 0x01, 0x02, 0x04, 0x08, 0x10, 0x2
14、0, 0x40, 0x80, 0x1b, 0x36; /轮常数 int i,j,m,n;for(m=0;m4;m+) for(n=0;n4;n+)ExpandKey0mn=Keyn*4+m; for(i=1;i11;i+) for(j=0;j4;j+)unsigned char Temp4; for(m=0; m4; m+)Tempm = j ? ExpandKeyimj-1 : ExpandKeyi-1m3; /进行两种划分,先把密钥存在一个变量数组中,if(j = 0)unsigned char t = Temp0;for(m=0; m3; m+)Tempm = SboxTemp(m+1)
15、%4;Temp3 = Sboxt;Temp0 = RCi-1;for(m=0; m4; m+) ExpandKeyimj =ExpandKeyi-1mj Tempm; / 4.2、加密加密流程图:4.2.1、字节代替(SubBytes)一AES定义了一个S盒,State中每个字节按照如下方式映射为一个新的字节:把该字节的高4位作为行值,低4位作为列值,然后取出S盒中对应行和列的元素作为输出。例如,十六进制数84。对应S盒的行是8列是4,S盒中该位置对应的值是5F。S盒是一个由16x16字节组成的矩阵,包含了8位值所能表达的256种可能的变换。S盒按照以下方式构造:(1) 逐行按照升序排列的字节
16、值初始化S盒。第一行是00,01,02,OF;第二行是10,l1,1F等。在行X和列Y的字节值是xy。(2) 把S盒中的每个字节映射为它在有限域GF()中的逆。GF代表伽罗瓦域,GF()由一组从0x00到0xff的256个值组成,加上加法和乘法。00被映射为它自身00。(3) 把S盒中的每个字节记成。对S盒中每个字节的每位做如下变换:上式中是指值为63字节C第i位,即。 符号()表示更新后的变量的值。AES用以下的矩阵方式描述了这个变换:最后完成的效果如图:二关键代码 直接采取让4x4矩阵的值进入S盒,这是因为数组元素的要求前四位作为行数,后四位作为列数,而元素值刚好是16进制表示形如:AB,
17、元素的值=A*16+B,这个刚好就是S盒的位置,void SubBytes(unsigned char State4) int i,j; for(i=0; i4; i+) for(j=0; j4; j+) Stateij = SboxStateij; 4.2.2、行移位(ShiftRows)一State的第一行字节保持不变,State的第二行字节循环左移一个字节,State的第三行字节循环左移两个字节,State的第四行循环左移三个字节。行移位左偏移量:变化如图2所示。二关键代码void ShiftRows(unsigned char State4) /采用最原始的办法,以分别为0.1.2.3
18、字节 unsigned char k; k=State10; State10=State11; State11=State12; State12=State13; State13=k; k=State21; State21=State23;State23=k;k=State20;State20=State22;State22=k; k=State33;State33=State32;State32=State31;State31=State30;State30=k;4.2.3、列混合(MixColumn)一列混合变换是一个替代操作,是AES最具技巧性的部分。它只在AES的第0,1,Nr一1轮中
19、使用,在第N r轮中不使用该变换。乘积矩阵中的每个元素都是一行和一列对应元素的乘积之和。在MixColumns变换中,乘法和加法都是定义在GF()上的。State的每一列 () 1=0,,3;J=0,被理解为 GF()上的多项式,该多项式与常数多项式相乘并模约化。这个运算需要做GF()上的乘法。但由于所乘的因子是三个固定的元素02、03、01,所以这些乘法运算仍然是比较简单的(注意到乘法运算所使用的模多项式为)。设一个字节为b=(b7b6b5b4b3b2b1b0),则b01=b; b02=(b6b5b4b3b2b1b00)+(000b7b70b7b7); b03=b01+b02。(请注意,加法
20、为取模2的加法,即逐比特异或)写成矩阵形式为:最后完成的效果如图:二关键代码/其中调用小函数xtime,根据02乘法原理编写,最后03乘是在02乘的基础上进行了03=(21+1 ),同理进行一次02乘,在与本省异或void MixColumns(unsigned char State4) unsigned char output44;int i, j; for(j=0; j 4; j+) for(i=0; i4; i+) outputij = xtime(Statei%4j) /0x02乘法 ( State ( i + 1 ) % 4j xtime( State ( i + 1 ) % 4j
21、) ) /0x03乘法 State ( i + 2 ) % 4j /0x01乘法 State ( i + 3 ) % 4j; /0x01乘法 for(i=0; i4; i+) for(j=0; j 4; j+)Stateij=outputij; 02乘法函数:unsigned char xtime (unsigned char input) int temp; temp = input1; if(input & 0x80) temp = 0x1b; return temp; 4.2.4、轮密钥加(AddRoundKey)一Add RoundKey称为轮密钥加变换,128位的State按位与 1
22、28位的密钥XOR:对 j=0, ,L-1 轮密钥加变换很简单,却影响了 State中的每一位。密钥扩展的复杂性和 AES的其他阶段运算的复杂性,却确保了该算法的安全性。最后完成的效果如图:二关键代码void AddRoundKey(unsigned char State4,unsigned char Key4) int i,j;for(i=0;i4;i+)for(j=0;j4;j+)Stateji=Keyji;4.2.5、加密主函数关键代码/根据加密函数流程图,进行架构加密主函数,参数分别是一个密钥数组,一个明文分组进入,参与运算,其中密钥一进入就进入密钥扩展,为以后的加密产生密钥,void
23、 Encryption(unsigned char input16,unsigned char Key16) KeyExpansion(Key,ExpandKey); unsigned char State44; int i,j,k; for(i=0; i4; i+) for(j=0; j4 ;j+) Stateij= input4*j+i; AddRoundKey(State,ExpandKey0); for(i=1; i=9) printf(n第%d轮加密密钥矩阵为:n,i); int m,n; for(m=0;m4;m+) for(n=0;n4;n+) printf(%X,ExpandK
24、eyinm); printf(n); printf(第%d轮加密出的密文为:,i); for(m=0;m4;m+) for(n=0;n4;n+) printf(%X,Statenm); printf(n); for(j=0; j4; j+) for(k=0; k4 ;k+)input4*k+j=Statejk; 4.3、解密解密流程:4.3.1、逆字节替代(InvSubBytes)关键代码与字节代替类似,逆字节代替基于逆S盒实现。直接进图逆S盒,原理很简单,与字节替代相同,只是盒子不同void InvSubBytes(unsigned char State4) int i,j; for(i=0
25、; i4; i+) for(j=0; j4; j+) Stateij = InvSboxStateij; 4.3.2、逆行移位(InvShiftRows)关键代码/与加密时的行移位区别在于移位方向相反。即向右移动void InvShiftRows(unsigned char State4) char k;k=State13; State13=State12;State12=State11;State11=State10;State10=k;k=State23; State23=State21; State21=k;k=State22;State22=State20;State20=k;k=St
26、ate30; State30=State31;State31=State32;State32=State33;State33=k;4.3.3、逆列混合(InvMixCloumns)关键代码/逆列混合操作与列混合一样,只是多项式d(x)不同,因而可以表示为矩阵相乘来实现,输入矩阵与固定矩阵(十六进制)相乘, void InvMixColumns(unsigned char State4) unsigned char output44; int i, j; for(j=0; j 4; j+) for(i=0; i4; i+) outputij = (xtime(xtime(xtime(Statei
27、 % 4j) xtime(xtime(Statei % 4j)xtime(Statei % 4j) /0x0E=14乘法 (xtime(xtime(xtime(State ( i + 1 ) % 4j) xtime(State ( i + 1 ) % 4j) State ( i + 1 ) % 4j) /0x0B=11乘法 (xtime(xtime(xtime(State ( i + 2 ) % 4j) xtime(xtime(State ( i + 2 ) % 4j) State ( i + 2 ) % 4j) /0x0D=13乘法 (xtime(xtime(xtime(State ( i
28、+ 3 ) % 4j) State ( i + 3 ) % 4j); /0x09乘法 for(i=0; i4; i+) for(j=0; j 4; j+)Stateij=outputij; 4.3.4、轮密钥加(AddRoundKey)与加密完全相同4.3.5、解密主函数关键代码/与加密函数不同的是,过程相反,根据流程图构造解密主函数,轮数相同,由于是AES本质是对称函数,所以是相反的而已void InvEncryption(unsigned char input16,unsigned char Key16) int i,j,k;KeyExpansion(Key,ExpandKey);unsi
29、gned char State44; for(j=0; j4; j+) for(k=0; k=0; i-) InvShiftRows(State);InvSubBytes(State); AddRoundKey(State, ExpandKeyi);if(i)InvMixColumns(State);if(i=1) /* 输出最后解密两轮密钥和密文 */ printf(n第%d轮密钥矩阵为:n,10-i); int m,n; for(m=0;m4;m+) for(n=0;n4;n+) printf(%X,ExpandKeyinm); printf(n); printf(第%d轮解密出的消息为:
30、,10-i); for(m=0;m4;m+) for(n=0;n4;n+) printf(%X,Statenm); printf(n); printf(n最后解密出的明文消息为:); for(int m=0;m4;m+) for(int n=0;n4;n+) printf(%c ,Statenm); printf(n);for(j=0;j4;j+) for(k=0; k4 ;k+) inputk*4+j = Statejk; 5.测试报告由于加密解密分两种方式,一种是由键盘输入进行加密解密。另一种是文件读入加密解密5.1主界面根据数字选择使用软件,下面分开测试:5.2测试键盘输入明文和密钥加密
31、键盘输入1,选择加密,并输入:IloveYouYouKnow? 共计16个字符,再任意输入16字符的密钥,为方便起见,测试时,输入为,最后加密成功之后输出中间密钥与密文状态其中最后加密密文为:A1,00,E9,BD,13,9A,CC,51,76,6A,3F,B8,AA,34,6A,C5.3测试键盘输入密文和密钥加密选择3,进入解密界面。为测试是否成功加密,采用上次加密时的密文进行输入,如图结果说明加密解密是成功的。5.3测试文件输入明文和密钥加密/选择2进入文件加密界面,输入保存有明文的文件名:Mingwen.txt.密钥文件名:Key.txt 输出到空文件State.txt中进行保存5.4测
32、试文件输入密文和密钥加密/选择4进入界面解密,同理,为检验是否加密成功,采用上次加密时密文输出到State.txt上的密文进行解密,密钥文件相同,与上图相比,结果正确。解密成功!5.5软件说明是为注明信息而设置,表明版权,可省略,6.课程设计报告总结这次课程设计我最大的收获就是凡事都要自己动手去做,有些事情自己不做,啥子都不会,有畏惧感,胆怯,始终把事情放在那,就形成恶性循环,这样子一直都做不来,一直都不会有进步,所以不管什么事情都要亲自去尝试一下,难易程度自己感知,不要听信他人的谣言,或者误导,以为怎么怎么样。还有就是,做代码的时候查阅了相关的书籍,很杂很乱,这对于选择有用的材料,有价值的材
33、料进行使用,会提高效率,最开始各种涉猎,很多,但是实用的却没有多少,白白耽误了很多时间。我觉得还是首先了解全局,了解总体,高屋建瓴,做好准备工作,写好报告,把每个过程搞懂了,才能动手去写代码,连基本的理论都不懂,就去操作,实在是慢,当然在了解的基础上,也要去实践,去检验自己的做法是否是对的,不能光搞理论,计算机是一个动手就得答案的科学,多检验,多算,多观察。这样子影响更深,更不会忘,一辈子的经验,自己动手得到的答案,远比查阅资料了解来的有意义,有效果。 在写代码的时候参考了一些参考资料,发现一些牛人啊,他们写的代码简介,精炼,确实让人敬佩,我用很多行代码实现的功能,别人两三句循环就解决了,主要
34、是平时没怎么编写代码,没有经验,还是要多写代码,多领悟,才能有他们的成就。而且我简介的代码都是很好的数学算法,我学的数学没怎么用在这个上面,不能直接用最低级的算法,最普通的算法,这样子永远不能简化,要简化就要用一些数学算法,下标改变啊,循环啊啥的这些可以实现意想不到的效果,实现功能和简介的双重母的。多实践! 最后我要感谢解放军信息工程大学的寻者,寻者是他的昵称,在我调试过程中,他给了我很大的帮助,真心的不知道说什么,我有很多的问题都是询问他解决的,而且那天他花了一整晚上的时间和我一起探讨,一起专研,帮我调试,这对于目前一个物质社会,节奏超快的社会,我真心感觉好幸运,好人还是多,这就坚定了我要做好人的决心。助人为乐,真心感觉很好!特别是那些在需要中的人们是、多么期盼的帮助。帮助别人就是帮助自己,万分感谢寻者!致敬!7.参考文献1 谭浩强.C程序设计(第三版). 北京:清华大学出版社, 20052张仕斌.张金全等. 应用密码学.西安电子科技大学出版社, 20093 寻者 .AES加密算法C+.