目 录 论文总页数:26页 1 引言 1 1.1 课题背景 1 1.2 国内外研究现状 1 1.3 本课题研究的意义 1 1.4 本课题的研究方法 1 2 相关数学基础 2 2.1 有限域GF (28) 2 2.2 数在GF (28)中的多项式 3 3 AES算法的设计准则及设计原理 4 3.1 分组密码通用准则 4 3.2 RIJNDAEL算法的设计原则和结构 5 3.3 RIJNDAEL算法加密轮变换原理 6 3.3.1 SubBytes变换 7 3.3.2 ShiftRows变换 8 3.3.3 MixColumns变换 8 3.3.4 AddRoundKey变换 9 3.4 子密钥生成算法 9 4 算法优化及实现研究 11 4.1 算法优化 11 4.2 RIJDAEL算法C语言的实现: 13 5 F1,F2,F3,F4,F5算法的研究 16 5.1 F1-F5的介绍 16 5.2 F1,F2,F3,F4,F5的实现 18 6 测试结果 22 结 论 24 参考文献 24 致 谢 25 声 明 26 1 引言 1.1 课题背景 第二代(2G)及2.5代(2.5G)移动通信系统,如GSM/GPRS,是当前正在广泛运行的移动通信系统,而第三代移动通信系统(3G)是当前通信领域研究开发的热点。在3G系统中,除了要开放语音业务外,还要开放电子商务、电子贸易、网络服务等新型的业务。为此,需要在网络系统中增加安全保护措施。若信息在网络中传输没有任何保护措施,就容易受到攻击或被窃听、被修改等,而直接影响用户的利益;若未经授权的业务直接接入到网络中来,也会影响运营商的利益。因此,如何保证系统的高安全性就显得十分重要。 1.2 国内外研究现状 在国际上,ETSI与3GPP两个基于GSM/GPRS网络和WCDMA与TD/SCDMA系统标准化的组织,特别是ETSI的SAGE与3GPP的S3工作组专门对网络安全方面的规范进行了研究。通过标准的制定和不断的研究,使得3G安全体系结构内的网络接入安全规范日趋成熟,无线链路的保密性和完整性算法也有一部分实现了标准化,但AKA协议中用到的相关算法却无需进行标准化,而由运营商或制造商自行确定。在国内,发展相对缓慢一点,但仍然取得了不小的成就。尽管各国的3G发展的进程不尽相同,但现有的移动通信网络向能够提供移动多媒体业务的3G网络演进是通信业发展的必然趋势。3G时代正在向我们靠近。 1.3 本课题研究的意义 此毕业设计是对3G中的一个安全协议(AKA)的服务网络端的实现加以分析和研究,以达到考查学生的专业基础知识和综合运用以及动手等多方面的能力,当然也包括以前所学的一些关于数论基础、网络、编程、信息安全等知识,同时也使学生了解当前移动通讯发展的新方向,理论联系实际,这才是当代大学生最重要但也是比较缺乏的一种能力,通过此次锻炼可以很好的锻炼学生的实际动手能力,又引导学生进行了一次模拟实际产品的开发,这是对学生在毕业前的一次重要考核,同时也为学生能很快的适应工作岗位奠定了良好的基础。
3.4 子密钥生成算法 子密钥是由密钥导出的,这个过程包含了两个组成部分,一个是密钥膨胀,另一个是轮子密钥的选取,如下原理: (1)轮子密钥的比特总数和等于分组长度乘以轮的数目加1,即每分组长128比特,轮数等于10时,轮子密钥的比特数总和为:128*(10+1)=1408比特。 (2)密钥扩充为密钥膨胀(Expanded Key)。 (3 )轮子密钥是由这些膨胀密钥中取出来的,第1轮子密钥由最先Nb个字组成,第2轮子密钥为次Nb个字,以此类推。密钥扩展如下图:
图7 密钥扩展示意图 图8 密钥扩展示意图 在密钥扩展中,函数ByteRotate(a,b,c,d)=(b,c,d,a),即是输入字的1字节循环。如下图所示:
图9 循环示意图
轮密钥的选取如下图:
图10 轮密钥选取示意图 4 算法优化及实现研究 4.1 算法优化 通过分析Rijndael算法,算法主要有三大模块组成:密钥扩展模块、明文加密模块和密文解密模块(此模块暂不讨论)。其中,密钥扩展模块由产生加密密钥的重要模块;明文加密模块是由SubByte变换、ShiftRows变换、MixColumns变换和AddRoundKey变换组成。 在Rijndael算法中,明文加密模块是核心,而影响其加密速度的是算法的轮变换,所以,要提高算法的效率,最重要的是精简算法的轮函数。 描述上为简单起见,这里选择128比特分组,密钥长度也是128比特。在SubByte变换中,假设输入为A,A=[ai,j] (0<=i, j<=3),输出为B,B= [bi,j](0<=i, j<=3 ),这里用: B=S[A] (1-21) 表示SubByte变换,也可以写为: bi,j=S[ai,j] (1-22) 在实际中,在这个变换中可以转换成查表操作,该表称为Rijndael算法的字节变换表,也可以称为S一盒,变换表如下表所示: 图11 S盒图 在ShiftRows变换中,该轮完成之后的输出为假设为C, C=[Ci,j ](0<=i, j<=3),用矩阵表示为: (1-23) 在MixColumns变换中,是在ShiftRows变换的结果看作在GF(28)域上的多项式,且把分组中的每一列与特殊多项式{03}x3+{ 0l}x2+{0l}x+{02}相乘(以多项式x4+1为模),设输出结果为D, D=[di,j] (0<=i, j<=3)即用矩阵表示为: (1-24) 在AddRoundKey变换中,这一轮密钥开始作用,轮密钥设为K, K=[ki,j]{0<=i,3<=j},这一轮的输出结果设为E, E=[ ei,j ]{0<=i,3<=j},用矩阵表示为: (1-25) 将上述各轮变换矩阵的上一轮输出结果带入到下一轮的输入中,用线性向量表示为
(1-26) 上述矩阵由五个矩阵异或而成,最后一个是密钥,这是在密钥扩展算法中产生的,前四个可以通过表S —盒做成查找表,这样,每轮操作的四个变换只需要4次查表,然后进行四次异或,这样就可以极大地提高算法的执行速度,为了便于表示,设: (1-27) (1-28) (1-29) (1-30) 所以,各轮的变换矩阵可简写为: E=B0 B1 B2 B3K (1-31) 4.2 Rijdael算法C语言的实现: 轮子密钥产生(RijndaelKeySchedule)的程序流程图:
图12 轮子密钥产生流程图 AES加密(RijndaelEncrypt)的程序流程图:
图13 AES加密的程序流程图
/*---------------查找表 ----------------------------*/(注:为了简化,则查找表ft_tab和f1_tab没给出具体值) static u32 rnd_con[10]= { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36}; static u32 ft_tab[4][256] static u32 fl_tab[4][256] static u32 Ekey[44]; /* 存放扩展密钥的数组 */ /*------ 4个表的产生 ------*/ #define f_rnd(x, n) \ ( ft_tab[0][byte0(x[n])] \ ^ ft_tab[1][byte1(x[(n + 1) & 3])] \ ^ ft_tab[2][byte2(x[(n + 2) & 3])] \ ^ ft_tab[3][byte3(x[(n + 3) & 3])] ) #define f_round(bo, bi, k) \ bo[0] = f_rnd(bi, 0) ^ k[0]; \ bo[1] = f_rnd(bi, 1) ^ k[1]; \ bo[2] = f_rnd(bi, 2) ^ k[2]; \ bo[3] = f_rnd(bi, 3) ^ k[3]; \ k += 4 /*--- S盒表的产生 ---*/ #define ls_box(x) \ ( fl_tab[0][byte0(x)] \ ^ fl_tab[1][byte1(x)] \ ^ fl_tab[2][byte2(x)] \ ^ fl_tab[3][byte3(x)] ) /*------------ 最后一轮 (没有 MixColumn) ----------*/ #define lf_rnd(x, n) \ ( fl_tab[0][byte0(x[n])] \ ^ fl_tab[1][byte1(x[(n + 1) & 3])] \ ^ fl_tab[2][byte2(x[(n + 2) & 3])] \ ^ fl_tab[3][byte3(x[(n + 3) & 3])] ) /*----------------------------------------------------------- * RijndaelKeySchedule(轮子密钥)函数的具体实现 */void RijndaelKeySchedule(u8 key[16]) { u32 t; /*t是个中间变量,用于存放右移24位的轮子密钥 */ u32 *ek=Ekey, /*指向Ekey的指针变量*/ *rc=rnd_con; /*把指针key指向的地址的值给数组Ekey的第一个元素*/ Ekey[0] = u32_in(key ); Ekey[1] = u32_in(key + 4); Ekey[2] = u32_in(key + 8); Ekey[3] = u32_in(key + 12); while(ek < Ekey + 40) { t = rot3(ek[3]); /*t为Ekey[3]右移8位的值*/ ek[4] = ek[0] ^ ls_box(t) ^ *rc++; /*byteSub和移位变化后与常量rc异或*/ ek[5] = ek[1] ^ ek[4]; ek[6] = ek[2] ^ ek[5]; ek[7] = ek[3] ^ ek[6]; ek += 4; |