密码学实验报告AESRSA.doc

上传人:小飞机 文档编号:5039077 上传时间:2023-05-31 格式:DOC 页数:18 大小:354.50KB
返回 下载 相关 举报
密码学实验报告AESRSA.doc_第1页
第1页 / 共18页
密码学实验报告AESRSA.doc_第2页
第2页 / 共18页
密码学实验报告AESRSA.doc_第3页
第3页 / 共18页
密码学实验报告AESRSA.doc_第4页
第4页 / 共18页
密码学实验报告AESRSA.doc_第5页
第5页 / 共18页
点击查看更多>>
资源描述

《密码学实验报告AESRSA.doc》由会员分享,可在线阅读,更多相关《密码学实验报告AESRSA.doc(18页珍藏版)》请在三一办公上搜索。

1、华北电力大学实 验 报 告| 实验名称 现代密码学课程设计 课程名称 现代密码学 | 专业班级: 学生姓名: 学 号: 成 绩:指导教师: 实验日期: 综合实验一 AES-128加密算法实现一、实验目的及要求(1)用C+实现;(2)具有16字节的加密演示;(3)完成4种工作模式下的文件加密与解密:ECB, CBC, CFB,OFB.二、所用仪器、设备计算机、Visual C+软件。三. 实验原理3.1、设计综述AES中的操作均是以字节作为基础的,用到的变量也都是以字节为基础。State可以用44的矩阵表示。AES算法结构对加密和解密的操作,算法由轮密钥开始,并用Nr表示对一个数据分组加密的轮数

2、(加密轮数与密钥长度的关系如表2所示)。AES算法的主循环State矩阵执行轮迭代运算,每轮都包括所有 4个阶段的代换,分别是在规范中被称为 SubBytes(字节替换)、ShiftRows(行位移变换)、MixColumns(列混合变换) 和AddRoundKey,(由于外部输入的加密密钥K长度有限,所以在算法中要用一个密钥扩展程序(Keyexpansion)把外部密钥 K 扩展成更长的比特串,以生成各轮的加密和解密密钥。最后执行只包括 3个阶段 (省略 MixColumns变换)的最后一轮运算。表2 AES参数密钥长度(bits)128192256明文分组长度(bits)128128128

3、轮数101214每轮密钥长度(bits)128128128扩展密钥长度(bytes)176206240基本要求按标准分组,以128比特为分组大小。所以轮数为10轮,密钥长度也为128比特。3.2、字节代替(SubBytes)AES定义了一个S盒,State中每个字节按照如下方式映射为一个新的字节:把该字节的高4位作为行值,低4位作为列值,然后取出S盒中对应行和列的元素作为输出。例如,十六进制数84。对应S盒的行是8列是4,S盒中该位置对应的值是5F。S盒是一个由16x16字节组成的矩阵,包含了8位值所能表达的256种可能的变换。S盒按照以下方式构造:(1) 逐行按照升序排列的字节值初始化S盒。

4、第一行是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用以下的矩阵方式描述了这个变换:最后完成的效果如图:3.3、行移位(ShiftRows)一State的第一行字节保持不变,State的第二行字节循环左移一个字节,State的第三行字节循环左移两个字节,St

5、ate的第四行循环左移三个字节。行移位左偏移量:变化如图2所示。3.4、列混合(MixColumn)一列混合变换是一个替代操作,是AES最具技巧性的部分。它只在AES的第0,1,Nr一1轮中使用,在第N r轮中不使用该变换。乘积矩阵中的每个元素都是一行和一列对应元素的乘积之和。在MixColumns变换中,乘法和加法都是定义在GF()上的。State的每一列 () 1=0,,3;J=0,被理解为 GF()上的多项式,该多项式与常数多项式相乘并模约化。这个运算需要做GF()上的乘法。但由于所乘的因子是三个固定的元素02、03、01,所以这些乘法运算仍然是比较简单的(注意到乘法运算所使用的模多项式

6、为)。设一个字节为b=(b7b6b5b4b3b2b1b0),则b01=b;b02=(b6b5b4b3b2b1b00)+(000b7b70b7b7);b03=b01+b02。(请注意,加法为取模2的加法,即逐比特异或)写成矩阵形式为:最后完成的效果如图:3.5、轮密钥加(AddRoundKey)Add RoundKey称为轮密钥加变换,128位的State按位与 128位的密钥XOR:对 j=0, ,L-1 轮密钥加变换很简单,却影响了 State中的每一位。密钥扩展的复杂性和 AES的其他阶段运算的复杂性,却确保了该算法的安全性。最后完成的效果如图:3.6.逆字节替换 通过逆S盒的映射变换得到

7、3.7.逆行移位InvShiftRow与加密时的行移位区别在于移位方向相反。3.8.逆列混淆3.9加密与解密模式电子密码本ECB模式:ECB模式是最古老,最简单的模式,将加密的数据分成若干组,每组的大小跟加密密钥长度相同;然后每组都用相同的密钥加密,比如DES算法,如果最后一个分组长度不够64位,要补齐64位;定义: Enc(X,Y)是加密函数Dec(X,Y)是解密函数Ci ( i = 0,1n)是密文块,大小为64bit; XOR(X,Y)是异或运算;IV是初始向量(一般为64位)ECB加密算法可表示为:C0 = Enc(Key, XOR(IV, P0) Ci = Enc(Key, XOR(

8、Ci-1, Pi) ECB解密算法可以表示为:P0 = XOR(IV, Dec(Key, C0)Pi = XOR(Ci-1, Dec(Key,Ci) 算法特点:每次加密的密文长度为64位(8个字节); 当相同的明文使用相同的密钥和初始向量的时候CBC模式总是产生相同的密文; 密文块要依赖以前的操作结果,所以,密文块不能进行重新排列; 可以使用不同的初始化向量来避免相同的明文产生相同的密文,一定程度上抵抗字典攻击; 一个错误发生以后,当前和以后的密文都会被影响;四、实验方法与步骤4.1 字节替换SubBytes()变换是一个基于S盒的非线性置换,它用于将输入或中间态的每一个字节通过一个简单的查表

9、操作,将其映射为另一个字节。映射方法是把输入字节的高四位作为S盒的行值,低四位作为列值,然后取出S盒中对应的行和列的元素作为输出。unsigned char subbytes(unsigned char state44) printf(after subbyte:n); /取出中间态state映射到S盒中的值赋给中间态statefor(i=0;i4;i+)for(j=0;j4;j+)stateij=sboxstateij; for(i=0;i4;i+) /输出到屏幕显示statefor(j=0;j4;j+)printf(tt%02x ,stateij); printf(n);printf(n)

10、; return 0; 4.2行移位ShiftRows()完成基于行的循环移位操作,变换方法是第0行不动,第一行循环左移一个字节,第二位循环左移两个字节,第三行循环左移三个字节。unsigned char shiftrows(unsigned char state44) printf(after shiftrows:n); / 在中间态的行上, k=state10; / 第0行不变 state10=state11; / 第一行循环左移一个字节 state11=state12; / 第二行循环左移两个字节 state12=state13; / 第三行循环左移三个字节 state13=k; k=s

11、tate20; state20=state22; state22=k; k=state21; state21=state23; state23=k; k=state30; state30=state33; state33=state32; state32=state31; state31=k; for(i=0;i4;i+) /输出到屏幕显示statefor(j=0;j4;j+)printf(tt%02x ,stateij); printf(n); printf(n); return 0; 4.3列混合MixColumns()实现逐列混合,方法是s(x)=c(x)*s(x)mod(x4+1)un

12、signed char mixcolumns(unsigned char state44) printf(after mixcolumns:n);/ 实现 (02 03 01 01) 与中间态state分别相乘后异或得相应值for(i=0;i4;i+) / (01 02 03 01) / (01 01 02 03) k=state0i; / (03 01 01 02) temp0 = state0i state1i state2i state3i ; temp1 = state0i state1i ; temp1 = xtime(temp1); state0i = temp1 temp0 ;

13、temp1 = state1i state2i ; temp1 = xtime(temp1); state1i = temp1 temp0 ; temp1 = state2i state3i ; temp1 = xtime(temp1); state2i = temp1 temp0 ; temp1 = state3i k ; temp1 = xtime(temp1); state3i = temp1 temp0 ; for(i=0;i4;i+) /输出到屏幕显示statefor(j=0;j4;j+)printf(tt%02x ,stateij); printf(n); printf(n);re

14、turn 0;4.4轮密钥加AddRoundKey()用于将输入或中间态S的每一列与一个密钥字ki进行按位异或,每一个轮密钥由Nb个字组成。unsigned char addroundkey(unsigned char state44,unsigned char w44)printf(addroundkey %d:n,round+); /将中间态state中的每一列与一个密钥字(w44中的一列)进行按位异或for(i=0;i4;i+) /完了又赋值给statefor(j=0;j4;j+)stateij=wij;for(i=0;i4;i+) /输出到屏幕显示出来statefor(j=0;j4;j

15、+)printf(tt%02x ,stateij);printf(n);printf(n); return 0; 4.5密钥扩展 通过生成器产生Nr+1个轮密钥,每个轮密钥由Nb个字组成,共有Nb(Nr+1)个字。在加密过程中,需要Nr+1个轮密钥,需要构造4(Nr+1)个32位字。首先将输入的4个字节直接复制到扩展密钥数组的前4个字中,得到W0,W1,W2,W3;然后每次用4个字填充扩展密钥数余下的部分。/keyexpand printf(after keyexpand:n);for(i=4;i8;i+) if(i%4=0) rotword0=w1i-1; rotword1=w2i-1; r

16、otword2=w3i-1; rotword3=w0i-1; printf(rotword():); for(j=0;j4;j+) printf(%02x ,rotwordj); for(j=0;j4;j+) subwordj=sboxrotwordj; printf(nsubword():); for(j=0;j4;j+) printf(%02x ,subwordj); printf(nn); for(j=0;j4;j+) rconj=subwordj RconNj ; printf(after Rcon():); for(j=0;j4;j+) printf(%02x ,rconj); pr

17、intf(nn);for(j=0;j4;j+) wji%4=rconj wji-4 ;printf(w%d :,count);for(j=0;j4;j+) printf( %02x ,wji%4) ; count+; else for(j=0;j4;j+)wji%4=wji%4wj(i%4)-1;printf(w%d :,count);for(j=0;j4;j+) printf( %02x ,wji%4); count+; printf(nn);printf(密钥扩展 Round key:n);for(i=0;i4;i+)for(j=0;j4;j+)printf(tt%02x ,wij);pr

18、intf(n);printf(n);4.6逆字节替换与字节代替类似,逆字节代替基于逆S盒实现。unsigned char InvSubbytes(unsigned char state44) for(i=0;i4;i+) /基于逆S盒的映射替代 for(j=0;j4;j+) stateij = rsboxstateij; printf(after InvSubbyte:n); for(i=0;i4;i+)for(j=0;j4;j+) /输出到屏幕显示stateprintf(tt%02x ,stateij); printf(n);printf(n);return 0;4.7逆行移位与行移位相反,

19、逆行移位将态state的后三行按相反的方向进行移位操作,即第0行保持不变,第1行循环向右移一个字节,第2行循环向右移动两个字节,第3行循环向右移动三个字节。unsigned char InvShiftRows(unsigned char state44) k=state13; state13=state12; /对中间态state进行移位操作 state12=state11; / 第0行保持不变 state11=state10; / 第1行循环右移一个字节 state10=k; / 第2行循环右移两个字节 / 第3行循环右移三个字节 k=state20; state20=state22; st

20、ate22=k; k=state21; state21=state23; state23=k; k=state30; state30=state31; state31=state32; state32=state33; state33=k;printf(after InvShiftRows:n);for(i=0;i4;i+) /输出到屏幕显示statefor(j=0;j4;j+)printf(tt%02x ,stateij); printf(n); printf(n); return 0;4.8逆列混合逆列混淆的处理办法与MixColumns()类似,每一列都通过与一个固定的多项式d(x)相乘

21、进行交换。unsigned char InvMixColumns(unsigned char state44)printf(after InvMixColumns :n); /实现(0e 0b 0d 09)与中间态state分别相乘后异或得相应值 for(i=0;i4;i+) / (09 0e 0b 0d) temp0 = state0i; / (0d 09 0e 0b) temp1 = state1i; / (0b 0d 09 0e) temp2 = state2i; temp3 = state3i; state0i = Multiply(temp0, 0x0e) Multiply(temp

22、1, 0x0b) Multiply(temp2, 0x0d) Multiply(temp3, 0x09); state1i = Multiply(temp0, 0x09) Multiply(temp1, 0x0e) Multiply(temp2, 0x0b) Multiply(temp3, 0x0d); state2i = Multiply(temp0, 0x0d) Multiply(temp1, 0x09) Multiply(temp2, 0x0e) Multiply(temp3, 0x0b); state3i = Multiply(temp0, 0x0b) Multiply(temp1,

23、0x0d) Multiply(temp2, 0x09) Multiply(temp3, 0x0e); for(i=0;i4;i+) /输出到屏幕显示statefor(j=0;j4;j+)printf(tt%02x ,stateij);printf(n);printf(n);return 0;4.9 加密加密部分我分了两种情况,一种是自动检查加密程序的正确性,之前在程序里给明文和密钥赋上初值,运行程序检验结果是否正确;另一种是用户手动输入32位的十六进制数,进行加密,我是把每一具体项模块化,将功能在每个具体模块中实现,只需要直接调用,视觉效果强,一目了然。 下面是实现加密功能一些关键代码void

24、 AES_encrypt(unsigned char StateN, unsigned char RoundKeyN)message16=0x32,0x43,0xf6,0xa8,0x88,0x5a,0x30,0x8d,0x31,0x31,0x98,0xa2,0xe0,0x37,0x07,0x34;key16=0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c; for(i=0;i4;i+) for(j=0;j4;j+) / 分别获取明文和密钥 stateji=messagem;wji=k

25、eym;m+; .addroundkey(state,w);for(round=2;round11;round+)printf(第 %d 轮加密 : n,round);subbytes(state); shiftrows(state);mixcolumns(state);keyexpand(w, round);addroundkey(state,w);subbytes(state); /最后一轮shiftrows(state);keyexpand(w, 10);addroundkey(state,w);4.10 解密AES解密我也是分成了两个部分,第一部分是在程序中对密文和密钥赋初值,通过与标

26、准对照检查解密过程的正确性;第二部分是用户手动输入密文和密钥,程序对其进行解密,得到最后的明文。解密过程基本如下:1)获取输入的明文和密钥 2)通过密钥扩展过程获取各轮密钥 3)轮密钥加变换过程 4)逆行移位 5)逆字节替代 6)轮密钥加变换 7)逆列混淆47步共9次循环,最后一轮实现46步,完成解密过程。主要代码如下:void AES_decrypt(unsigned char StateN, unsigned char wN)key16=0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x

27、3c;cipher16=0x39,0x25,0x84,0x1d,0x02,0xdc,0x09,0xfb,0xdc,0x11,0x85,0x97,0x19,0x6a,0x0b,0x32;printf(%02x ,keyi);printf(n); /获取密文和密钥 for(i=0;i4;i+) for(j=0;j 0; i -)/1-9轮 InvShiftRows(state);InvSubbytes(state);Keyexpand(w,round );AddRoundKey(State, w); InvMixColumns(State);InvShiftRows(State); /最后一轮In

28、vSubBytes(State); Keyexpand(w,0 );AddRoundKey(State, w);五、实验结果与数据处理实验结果截图:六、实验心得这次课程设计我最大的收获就是凡事都要自己动手去做,有些事情自己不做,什么都不会,有畏惧感,胆怯,始终把事情放在那,就形成恶性循环,这样子一直都做不来,一直都不会有进步,所以不管什么事情都要亲自去尝试一下,难易程度自己感知,不要听信他人的谣言,或者误导。还有就是,做代码的时候查阅了相关的书籍,很杂很乱,这对于选择有用的材料,有价值的材料进行使用,会提高效率,最开始各种涉猎,很多,但是实用的却没有多少,白白耽误了很多时间。我觉得还是首先了解

29、全局,了解总体,高屋建瓴,做好准备工作,写好报告,把每个过程搞懂了,才能动手去写代码,连基本的理论都不懂,就去操作,实在是慢,当然在了解的基础上,也要去实践,去检验自己的做法是否是对的,不能光搞理论,计算机是一个动手就得答案的科学,多检验,多算,多观察。这样子影响更深,更不会忘,一辈子的经验,自己动手得到的答案,远比查阅资料了解来的有意义,有效果。在写代码的时候参考了一些参考资料,发现一些牛人写的代码简介,精炼,确实让人敬佩,我用很多行代码实现的功能,别人两三句循环就解决了,主要是平时没怎么编写代码,没有经验,还是要多写代码,多领悟,才能有他们的成就。而且我简介的代码都是很好的数学算法,我学的

30、数学没怎么用在这个上面,不能直接用最低级的算法,最普通的算法,这样子永远不能简化,要简化就要用一些数学算法,下标改变啊,循环啊啥的这些可以实现意想不到的效果,实现功能和简介的双重母的。多实践!综合实验 二 RSA加密算法的实现一、实验目的及要求通过编程实现RSA的加密和解密过程,加深对公钥(非对称)密码算法的认识二、所用仪器、设备计算机、Visual C#软件。三、实验原理1.RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。 RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。RSA的安全性依赖

31、于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。2.RSA的安全性依赖于大数分解。公钥和私钥都是两个大素数( 大于 100个十进制位)的函数。据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大素数的积。 3.密钥对的产生。选择两个大素数,p 和q 。计算:n = p * q,然后随机选择加密密钥e(PS:最常用的e值有3,17和65537,微软就是使用的65537,采用3个中的任何一个都不存在安全问题),要求 e 和 ( p - 1 ) * ( q - 1 ) 互质。最后,利用Euclid 算法计算解密密钥d, 满足e * d = 1 ( mod ( p - 1

32、 ) * ( q - 1 ) )其中n和d也要互质。数e和n是公钥,d是私钥。两个素数p和q不再需要,应该丢弃,不要让任何人知道。 4.加密信息 m(二进制表示)时,首先把m分成等长数据块 m1 ,m2,., mi ,块长s,其中 2s = n, s 尽可能的大。对应的密文是: ci = mie ( mod n ) ( a ) 解密时作如下计算: mi = cid ( mod n ) ( b )5.从RSA的原理来看,公钥加密私钥解密和私钥加密公钥解密应该是等价的,在某些情况下,比如共享软件加密,我们需要用私钥加密注册码或注册文件,发给用户,用户用公钥解密注册码或注册文件进行合法性验证。四、实

33、验方法与步骤.NET提供常用的加密算法类,支持RSA的类是RSACryptoServiceProvider(命名空间:System.Security.Cryptography),但只支持公钥加密,私钥解密。 RSACryptoServiceProvider类包括:Modulus、Exponent、P、Q、DP、DQ、InverseQ、D等8个属性,其中Modulus和Exponent就是公钥,Modulus和D就是私钥,RSACryptoServiceProvider类提供导出公钥的方法,也提供导出私钥的方法,导出的私钥包含上面8个属性。五、实验结果与数据处理主要代码如下:六、实验心得通过这次

34、的实验,了解了非对称密码算法RSA,会运用一些现成的算法进行编程,对一些比较复杂的算法开始基本认识并深刻的掌握。在以后所涉及这方面的知识将会有全新的了解和掌握通过这次课程设计,我对RSA加密体制有了更进一步的了解。遇到的主要问题是如何将明文按照比特分组并对其实现RSA加密,以及对大素数的处理。最终大素数的处理得以实现,但明文分组并没有找到合适的方法,这就要求我在课程设计后去学习怎样为明文分组机密。要想学好现代密码学不仅要学习好密码学相关知识,还要有很好的数学基础,还有很强的编程能力,课程设计时对学生个人综合能力的检验。任何知识和技术都不是孤立的。要学习好密码学要牵扯到线性代数,离散数学,概率统计等数学知识,为了验证加密解密算法的正确性,还要动手编制程序,这就要求学生要对至少一种编程技术有所熟知。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号