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

  • 格式:doc
  • 大小:357.00 KB
  • 文档页数:18

华北电力大学

实 验 报 告

|

|

实验名称 现代密码学课程设计

课程名称 现代密码学

|

|

专业班级: 学生姓名:

学 号: 成 绩:

指导教师: 实验日期: 华 北 电 力 大 学 实 验 报 告

第 页 共 页 [综合实验一] 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rN轮迭代运算,每轮都包括所有 4个阶段的代换,分别是在规范中被称为 SubBytes(字节替换)、ShiftRows(行位移变换)、MixColumns(列混合变换) 和AddRoundKey,(由于外部输入的加密密钥K长度有限,所以在算法中要用一个密钥扩展程序(Keyexpansion)把外部密钥 K 扩展成更长的比特串,以生成各轮的加密和解密密钥。最后执行只包括 3个阶段 (省略 MixColumns变换)的最后一轮运算。

表2 AES参数

密钥长度(bits) 128 192 256

明文分组长度(bits) 128 128 128

轮数 10 12 14

每轮密钥长度(bits) 128 128 128

扩展密钥长度(bytes) 176 206 240

基本要求按标准分组,以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盒。第一行是{00},{01},{02},…,{OF};第二行是{10},{l1},…,{1F}等。在行X和列Y的字节值是{xy}。

(2) 把S盒中的每个字节映射为它在有限域GF(k2)中的逆。GF代表伽罗瓦域,GF(82)由一组从0x00到0xff的256个值组成,加上加法和乘法。)1(][2)2(3488xxxxXZGF。{00}被映射为它自身{00}。

(3) 把S盒中的每个字节记成),,,,,,,,(012345678bbbbbbbbb。对S盒中每个字节的每位做如下变换:

iiiiiicbbbbbib8mod)7(8mod)6(8mod)5(8mod)4(

上式中ic是指值为{63}字节C第i位,即)01100011(),,,,,,,,(012345678ccccccccc。符号(')表示更新后的变量的值。AES用以下的矩阵方式描述了这个变换:

0110001111111000011111000011111000011111100011111100011111100011111100017654321076543210bbbbbbbbbbbbbbbb

最后完成的效果如图:

华 北 电 力 大 学 实 验 报 告

第 页 共 页

3.3、行移位(ShiftRows)

一.State的第一行字节保持不变,State的第二行字节循环左移一个字节,State的第三行字节循环左移两个字节,State的第四行循环左移三个字节。

行移位左偏移量:

变化如图2所示。

3.4、列混合(MixColumn) 华 北 电 力 大 学 实 验 报 告

第 页 共 页 一.列混合变换是一个替代操作,是AES最具技巧性的部分。它只在AES的第0,1,…,Nr一1轮中使用,在第N r轮中不使用该变换。乘积矩阵中的每个元素都是一行和一列对应元素的乘积之和。在MixColumns变换中,乘法和加法都是定义在GF(82)上的。State的每一列 (jib,) 1=0,…,3;J=0,…,bL被理解为 GF(82)上的多项式,该多项式与常数多项式012233)(axaxaxaxa相乘并模1)(4xxM约化。

这个运算需要做GF(82)上的乘法。但由于所乘的因子是三个固定的元素02、03、01,所以这些乘法运算仍然是比较简单的(注意到乘法运算所使用的模多项式为1)(348xxxxxm)。设一个字节为b=(b7b6b5b4b3b2b1b0),则

bב01’=b;

bב02’=(b6b5b4b3b2b1b00)+(000b7b70b7b7);

bב03’=bב01’+b×’02’。

(请注意,加法为取模2的加法,即逐比特异或)

写成矩阵形式为:

00112233ba02030101ba01020301b01010203a03010102ba

最后完成的效果如图:

华 北 电 力 大 学 实 验 报 告

第 页 共 页 3.5、轮密钥加(AddRoundKey)

Add RoundKey称为轮密钥加变换,128位的State按位与 128位的密钥XOR:),,,(),,,(),,,(321032103210jjjjjjjjjjjjkkkkbbbbbbbb对 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盒中的值赋给中间态state

for(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];