当前位置:文档之家› 密码学实验报告(AES,RSA)

密码学实验报告(AES,RSA)

华北电力大学实验报告||实验名称现代密码学课程设计课程名称现代密码学||专业班级:学生姓名:学号:成绩:指导教师:实验日期:[综合实验一] AES-128加密算法实现 一、实验目的及要求(1)用C++实现;(2)具有16字节的加密演示;(3)完成4种工作模式下的文件加密与解密:ECB, CBC, CFB,OFB.二、所用仪器、设备计算机、Visual C++软件。

三. 实验原理3.1、设计综述AES 中的操作均是以字节作为基础的,用到的变量也都是以字节为基础。

State 可以用4×4的矩阵表示。

AES 算法结构对加密和解密的操作,算法由轮密钥开始,并用Nr 表示对一个数据分组加密的轮数(加密轮数与密钥长度的关系如表2所示)。

AES 算法的主循环State 矩阵执行1 r N 轮迭代运算,每轮都包括所有 4个阶段的代换,分别是在规范中被称为 SubBytes(字节替换)、ShiftRows(行位移变换)、MixColumns(列混合变换) 和AddRoundKey ,(由于外部输入的加密密钥K 长度有限,所以在算法中要用一个密钥扩展程序(Keyexpansion)把外部密钥 K 扩展成更长的比特串,以生成各轮的加密和解密密钥。

最后执行只包括 3个阶段 (省略 MixColumns 变换)的最后一轮运算。

表2 AES 参数比特。

3.2、字节代替(SubBytes )AES 定义了一个S 盒,State 中每个字节按照如下方式映射为一个新的字节:把该字节的高4位作为行值,低4位作为列值,然后取出S 盒中对应行和列的元素作为输出。

例如,十六进制数{84}。

对应S 盒的行是8列是4,S 盒中该位置对应的值是{5F}。

S 盒是一个由16x16字节组成的矩阵,包含了8位值所能表达的256种可能的变换。

S 盒按照以下方式构造:(1) 逐行按照升序排列的字节值初始化S 盒。

第一行是{00},{01},{02},…,{OF};第二行是{10},{l1},…,{1F}等。

在行X 和列Y 的字节值是{xy}。

(2) 把S 盒中的每个字节映射为它在有限域GF(k 2)中的逆。

GF 代表伽罗瓦域,GF(82)由一组从0x00到0xff 的256个值组成,加上加法和乘法。

)1(][2)2(3488++++=x x x x X Z GF 。

{00}被映射为它自身{00}。

(3) 把S 盒中的每个字节记成),,,,,,,,(012345678b b b b b b b b b 。

对S 盒中每个字节的每位做如下变换:i i i i i i c b b b b b i b ⊕⊕⊕⊕⊕='++++8mod )7(8mod )6(8mod )5(8mod )4(上式中i c 是指值为{63}字节C 第i 位,即)01100011(),,,,,,,,(012345678=c c c c c c c c c 。

符号(')表示更新后的变量的值。

AES 用以下的矩阵方式描述了这个变换:⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡+⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡=⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡0110001111111000011111000011111000011111100011111100011111100011111100017654321076543210b b b b b b b b b b b b b b b b最后完成的效果如图:3.3、行移位(ShiftRows)一.State的第一行字节保持不变,State的第二行字节循环左移一个字节,State 的第三行字节循环左移两个字节,State的第四行循环左移三个字节。

行移位左偏移量:变化如图2所示。

3.4、列混合(MixColumn)一.列混合变换是一个替代操作,是AES 最具技巧性的部分。

它只在AES 的第0,1,…,Nr 一1轮中使用,在第N r 轮中不使用该变换。

乘积矩阵中的每个元素都是一行和一列对应元素的乘积之和。

在MixColumns 变换中,乘法和加法都是定义在GF(82)上的。

State 的每一列 (j i b ,) 1=0,…,3;J=0,…,b L 被理解为 GF(82)上的多项式,该多项式与常数多项式012233)(a x a x a x a x a +++=相乘并模1)(4+=x x M 约化。

这个运算需要做GF(82)上的乘法。

但由于所乘的因子是三个固定的元素02、03、01,所以这些乘法运算仍然是比较简单的(注意到乘法运算所使用的模多项式为1)(348++++=x x x x x m )。

设一个字节为b=(b7b6b5b4b3b2b1b0),则b ב01’=b;b ב02’=(b6b5b4b3b2b1b00)+(000b7b70b7b7); b ב03’=bב01’+b×’02’。

(请注意,加法为取模2的加法,即逐比特异或) 写成矩阵形式为:00112233b a 02030101b a 01020301b 01010203a 03010102b a ⎡⎤⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥=⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦⎣⎦最后完成的效果如图:3.5、轮密钥加(AddRoundKey )Add RoundKey 称为轮密钥加变换,128位的State 按位与 128位的密钥XOR :),,,(),,,(),,,(321032103210j j j j j j j j j j j j k k k k b b b b b b b b ⊕←对 j=0,… ,L-1 轮密钥加变换很简单,却影响了 State 中的每一位。

密钥扩展的复杂性和 AES 的其他阶段运算的复杂性,却确保了该算法的安全性。

最后完成的效果如图:3.6.逆字节替换通过逆S 盒的映射变换得到3.7.逆行移位InvShiftRow与加密时的行移位区别在于移位方向相反。

3.8.逆列混淆3.9加密与解密模式电子密码本ECB模式:ECB模式是最古老,最简单的模式,将加密的数据分成若干组,每组的大小跟加密密钥长度相同;然后每组都用相同的密钥加密,比如DES算法,如果最后一个分组长度不够64位,要补齐64位;定义: Enc(X,Y)是加密函数Dec(X,Y)是解密函数Ci ( i = 0,1…n)是密文块,大小为64bit; XOR(X,Y)是异或运算;IV是初始向量(一般为64位)ECB加密算法可表示为:C0 = Enc(Key, XOR(IV, P0)Ci = Enc(Key, XOR(Ci-1, Pi)ECB解密算法可以表示为:P0 = XOR(IV, Dec(Key, C0))Pi = XOR(Ci-1, Dec(Key,Ci))算法特点:每次加密的密文长度为64位(8个字节); 当相同的明文使用相同的密钥和初始向量的时候CBC模式总是产生相同的密文; 密文块要依赖以前的操作结果,所以,密文块不能进行重新排列; 可以使用不同的初始化向量来避免相同的明文产生相同的密文,一定程度上抵抗字典攻击; 一个错误发生以后,当前和以后的密文都会被影响;四、实验方法与步骤4.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;}4.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;}4.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;}4.4轮密钥加AddRoundKey()用于将输入或中间态S的每一列与一个密钥字ki进行按位异或,每一个轮密钥由Nb个字组成。

相关主题