密码学课程设计报告

更新时间:2024-05-05 01:21:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

中 国 矿 业 大 学

密码学课程设计报告

学 院:班 级:姓 名:学 号:指导教师:

计算机科学与技术学院 信安11-2班

08113761 谢 林 2014 年 6月

密码学课程设计

目录

实验一 HILL算法的实现 .................................................. 3

1.1 HILL算法概述 ............................................................................... 3

1.2算法原理与设计思路 ...................................................................... 3 1.3 实验代码 ......................................................................................... 5 1.4 关键算法分析 ............................................................................... 11 1.5 运行结果分析 ............................................................................... 12 1.6 算法安全性分析 ........................................................................... 13

实验二 MD5算法的实现 ................................................. 14

2.1 MD5算法概述 ................................................................................ 14

2.2 算法原理与设计思路 ................................................................... 15 2.3 实验代码 ....................................................................................... 17 2.4 关键算法分析 ............................................................................... 25 2.5 运行结果 ....................................................................................... 28 2.6算法安全性分析 ............................................................................ 28

实验三 AES算法的实现 .................................................. 29

3.1 AES算法概述 ................................................................................ 31

3.2 算法原理与设计思路 ................................................................... 33 3.3 实验代码 ....................................................................................... 33 3.4 关键算法分析 ............................................................................... 42 3.5 运行结果 ....................................................................................... 44 3.6 算法安全性分析 ........................................................................... 44

实验四 ECC算法的实现(选做) ........................................... 29

4.1 ECC算法概述 ................................................................................ 29

4.2 算法原理与设计思路 ................................................................... 29 4.3 实验代码 ....................................................................................... 29 4.4 运行结果 ....................................................................................... 29 4.5 ECC自主探究 ................................................................................ 50

五 实验总结 ........................................................... 51

2

密码学课程设计

实验一 HILL算法的实现

1.1 HILL算法概述

Hil加密算法的基本思想是将个明文字母通过线性变换将它们转换为k个密文字母。脱密只要做一次逆变换就可以了,密钥就是变换矩阵本身。

M=m1m2……ml Ek(M)=c1c2……cl

c1=k11m1+k12m2+……+k1lml c2=k21m1+k22m2+……+k2lm ??

cl=kl1m1+kl2m2+……+kllml

通常对于字母加解密,使mod 26的方法,以上线性方程可以采用矩阵表示。 或写成 C?KM (mod 26),其中:

C=

, M=, K=(kij)l?l , M=K-1C (mod 26)

1.2算法原理与设计思路

图1 密码体制

一个密码系统,通常简称为密码体制(Cryptosystem),由五部分组成(如图1.4所示):

(1)明文空间M,它是全体明文的集合; (2)密文空间C,它是全体密文的集合;

(3)密钥空间K,它是全体密钥的集合。其中每 一个密钥K均由加密密钥Ke和解密密钥Kd组成,即K=? Ke, Kd ?;

3

密码学课程设计

(4)加密算法E,它是一组由M到C的加密变换; (5)解密算法D,它是一组由C到M的解密变换。

如果一个密码体制由其中一个很容易推出另一个,则称为单密钥密码体制或对称密码体制或传统密码体制。而HILL密码体制就是一个典型的例子: Hill加密算法的基本思想是将l个明文字母通过线性变换.将它们转换为l个密文字母。解密只要作一次逆变换就可以了。密钥就是变换矩阵本身,即 :

M=m1 m2 … ml, Ek ( M )=c1 c2 … cl, 其中

c1=k11 m1+k12 m2+… +k1l ml c2=k21 m1+k22 m2+… +k2l ml ……

ct=kl1 m1+kl2 m2+… +kll ml 或写成

C=KM mod n 其中

K=( ki j )l×l

M=K ?1 C mod n

例如,l=4,n=26时有:

11

22

ll

?8 6 9 10? ?23 20 5 1???6 9 5 10? ??? 2 11 18 1K?-1? K???5 8 4 9?? 2 20 6 25? ????10 6 11 425 2 22 25?? ??

?8 6 9 10??23 20 5 1??339 416 312 364? ???????6 9 5 10?? 2 11 18 1???416 339 442 390? ?5 8 4 9?? 2 20 6 25??364 286 339 338??????? ?10 6 11 4??25 2 22 25??364 494 332 131??1 0 0 0?

??0 1 0 0?? ?mod26?0 0 0 1??? 0 0 0 1?c?c?C????c??m?????,M??m?????????m???4

密码学课程设计

若采用从A到Z的26个字母依顺序从0到25编号,M可分别得数字化后4个数字:7,8,11,11,这样 已知M=Hill 因此C=YTIX。

在了解了相应的基础后,可以将程序的设计分为以下几个模块:

1)明文输入模块;

可以简单的设置一个数组存储输入的明文,并定义相应的操作管理明文的输入过程。 2)密钥生成模块;

为了得到密钥,首先可以定义一个二维数组,调用随机数生成函数,结合模26下的模逆算法以及判断矩阵是否可逆,不可逆则重新调用随机生成函数生成密钥。 3)加密运算模块;

加密的本质是对密钥矩阵的n行与明文列相乘后求和得到n个密文,注意到是在模26下的乘法,也应该对结果做相应的处理。 4)密文输出模块;

定义相应的操作和机制,使得密文的输出更合理顺畅。

1.3 实验代码如下: #include #include #include #include using namespace std; const int M=5; int gcd(int a,int b) { if(a%b==0)return b; return gcd(b,a%b); }

string encryption_or_decryption(int a1,int a2 ,string s1,int a[M][M]) { string s2; int Plaintext[M];//明文数组 int ciphertext[M]={0};//密文数组 for(int i=0;i

5

密码学课程设计

} ciphertext[i]%=26; if(ciphertext[i]<0)ciphertext[i]+=26; char dd = ciphertext[i] + a2; s2.push_back(dd); } return s2; }

int DET(int n ,int c [M][M]) {

if(n==2)return c[0][0]*c[1][1]-c[0][1]*c[1][0];

int i_1,j_1,d; //d为数组b的行 int b[M][M]; //用于存放余子式 int p=0,q=0; int sum=0;

for(i_1=0;i_1

for(d=0;d

if(d

for(j_1=0;j_1

b[d][j_1]=c[d+p][j_1+1]; } } if(i_1%2==0) q=1; else q=-1; sum=sum+c[i_1][0]*q*DET(n-1,b); }

return sum; }

void show() { cout<<\

***********************************************************\ cout<<\

***********************************************************\ cout<<\ ****************** 欢迎使用加解密系统 ***************\

6

密码学课程设计

cout<<\ **************请根据提示输入秘钥、明文和密文***************\ cout<<\

***********************************************************\ cout<<\

***********************************************************\ cout<<\按回车键有电脑随机生成秘钥矩阵\ system(\ cout<

int main() { show(); srand(time(0)); next: int a[M][M];//存储原矩阵 int _a[M][M];//a的逆矩阵 int b[M][M];//a储伴随矩阵 int det = 0; //行列式 int _det = 0; //行列式的逆 for(int i=0;i7

密码学课程设计

int A_i_j=0; int c[M][M];//用于存储余子式的矩阵 int q=0;//行 int p=0;//列 //下面这两个循环完成了除去第i行第j列的余子式 for(int k=0;k

8

密码学课程设计

cout<<\行列式与26的公约数\ if(gcd(det,26)!=1 && gcd(det,26)!= -1) { cout<<\该秘钥不存在逆矩阵,按回车键重新随机生成新的秘钥矩阵:\ system(\ goto next; } det = det % 26; if(det<0)det+=26; for(int k= 0;k<26;k++) { if((k*26+1)Tt==0) { _det = (k*26+1)/det; break; } } cout<<\行列式的逆为:\ for(int i=0;i

9

密码学课程设计

next1: cout<<\******************* 1:加****************************\ cout<<\******************* 2:解****************************\ cout<<\******************* 3:退****************************\ cout<<\******************* 4:更改秘****************************\ int nn; cin>>nn; int a1=65,a2=97; if(nn==1) { string s1,s2; cout<<\请输入输入明文:\ cin>>s1; s2 = encryption_or_decryption(a2,a1,s1,a); cout<<\密文为: \ goto next1; } else if(nn==2) { string s1,s2; cout<<\请输入输入密文:\ cin>>s1; s2 = encryption_or_decryption(a1,a2,s1,_a); cout<<\解密后的明文: \ goto next1; } else if(nn==3) { cout<<\谢谢使用加解密系统,本程序结束\ return 0; } else if(nn==4) { goto next; } else { cout<<\输入错误,请重新输入:\

10

密 密 出 钥

密码学课程设计

}

goto next1;

1.4 关键算法分析

(1)如何快速求两个数的公约数。 int gcd(int a,int b) { if(a%b==0)return b; return gcd(b,a%b); }

(2)如何执行加密和解密运算。

//下面是加密或者解密函数,需要4个参数:a1 ,a2, s1,密钥数组。 string encryption_or_decryption(int a1,int a2 ,string s1,int a[M][M]) { string s2; int Plaintext[M];//明文数组 int ciphertext[M]={0};//密文数组 for(int i=0;i

return s2;

}

(3)求行列式的值。

//下面这个函数是用来计算行列式的,计算行列式的目的是为了判断矩阵是否可逆。

int DET(int n ,int c [M][M]) {

if(n==2)return c[0][0]*c[1][1]-c[0][1]*c[1][0];

int i_1,j_1,d; //d为数组b的行 int b[M][M]; //用于存放余子式

11

密码学课程设计

int p=0,q=0; int sum=0;

for(i_1=0;i_1

for(d=0;d

if(d

for(j_1=0;j_1

b[d][j_1]=c[d+p][j_1+1]; } }

if(i_1%2==0) q=1; else q=-1;

sum=sum+c[i_1][0]*q*DET(n-1,b); }

return sum; }

1.5 运行结果分析

如下是我的程序运行时的界面:

图1-2

让电脑随机生成1到100的整数,随机生成的矩阵不一定能成为秘钥,根据条件 gcd(det K,26)=1进行判断,如图2:

12

密码学课程设计

图1-3

尝试成功后使用下面矩阵为秘钥矩阵:

图1-4

执行更改秘钥功能,如图5:

图 1-5

输入1 加密,输入2解密,如下图1-6:

13

密码学课程设计

图1-6

图7

由图7可知,明文和密文经加密和解密后前后相同,说明程序运行正确。

1.6 安全性分析

根据相应的加密原理可知:希尔密码加密矩阵的阶数越大,破译的难度越大。而希尔密码在一定程度上克服了传统密码在统计学规律上的不足,能够抵御一般的频率分析法但是其基于线性变换的安全性是极其脆弱的,攻击者截取一定数目的明文和密文对就可以通过线性运算得到相应的密钥。另外,在计算机算力飞速发展的今天,通过遍历希尔密码的密钥空间破解相应的密钥已经是很简单的事了。

实验二 MD5算法的实现

2.1 MD5算法概述

MD5、SHA-1是当前国际通行的两大标准 MD5由国际著名密码学家、图灵奖获得者兼公钥加密算法RSA的创始人Rivest设计,SHA-1由美国制定密码算法的标准机构—美国国家标准技术研究院(NIST)与美国国家安全局(NSA)设计两大算法是数字签名及许多其它密码应用领域的关键技术,广泛应用于金融、证券等电子商务领域 SHA-1早在1994年便为美国政府采纳,目前是美国政府广泛应用的Hash函数密码算法。

14

密码学课程设计

对MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。 MD5的典型应用是对一段信息(Message)产生信息摘要(Message-Digest),以防止被篡改。比如,在UNIX下有很多软件在下载的时候都有一个文件名相同,文件扩展名为.md5的文件,在这个文件中通常只有一行文本,大致结构如:

MD5 (tanajiya.tar.gz) = 0ca175b9c0f726a831d895e269332461

这就是tanajiya.tar.gz文件的数字签名。MD5将整个文件当作一个大文本信息,通过其不可逆的字符串变换算法,产生了这个唯一的MD5信息摘要。如果在以后传播这个文件的过程中,无论文件的内容发生了任何形式的改变(包括人为修改或者下载过程中线路不稳定引起的传输错误等),只要你对这个文件重新计算MD5时就会发现信息摘要不相同,由此可以确定你得到的只是一个不正确的文件。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的\抵赖\,这就是所谓的数字签名应用。

MD5还广泛用于加密和解密技术上。比如在UNIX系统中用户的密码就是以MD5(或其它类似的算法)经加密后存储在文件系统中。当用户登录的时候,系统把用户输入的密码计算成MD5值,然后再去和保存在文件系统中的MD5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这不但可以避免用户的密码被具有系统管理员权限的用户知道,而且还在一定程度上增加了密码被破解的难度。

2.2算法原理与设计思路

在MD5算法中,首先需要对信息进行填充,使其位长对512求余的结果等于448。因此,信息的位长(Bits Length)将被扩展至N*512+448,N为一个非负整数,N可以是零。填充的方法如下,在信息的后面填充一个1和无数个0,直到满足上面的条件时才停止用0对信息的填充。然后,在这个结果后面附加一个以64位二进制表示的填充前信息长度。经过这两步的处理,现在的信息的位长=N*512+448+64=(N+1)*512,即长度恰好是512的整数倍。这样做的原因是为满足后面处理中对信息长度的要求。总体流程如下图所示,

表示第i个分组,每次的运算都由前一轮的128位结果值和第i块512bit值进行运算。初始的128位值为初试链接变量,这些参数用于第一轮的运算,以大端字节序来表示,他们分别为:A=0x01234567,B=0x89ABCDEF,C=0xFEDCBA98,D=0x76543210。

15

密码学课程设计

} else i = 0;

/* Buffer remaining input */

/*将输入缓冲区中的不足填充满512bits的剩余内容填充到context->buffer中,留待以后再作处理*/

R_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i); }

/* MD5 finalization. Ends an MD5 message-digest operation, writing the the message digest and zeroizing the context. */ /*获取加密 的最终结果 digest:保存最终的加密串

context:你前面初始化并填入了信息的md5结构 */

void MD5Final (unsigned char digest[16],MD5_CTX *context) {

unsigned char bits[8];

unsigned int index, padLen;

/* Save number of bits */

/*将要被转换的信息(所有的)的bits长度拷贝到bits中*/ Encode(bits, context->count, 8);

/* Pad out to 56 mod 64. */

/* 计算所有的bits长度的字节数的模64, 64bytes=512bits*/ index = (unsigned int)((context->count[0] >> 3) & 0x3f);

/*计算需要填充的字节数,padLen的取值范围在1-64之间*/ padLen = (index < 56) ? (56 - index) : (120 - index);

/*这一次函数调用绝对不会再导致MD5Transform的被调用,因为这一次不会填满512bits*/

MD5Update(context, PADDING, padLen);

/* Append length (before padding) */

/*补上原始信息的bits长度(bits长度固定的用64bits表示),这一次能够恰巧凑够512bits,不会多也不会少*/ MD5Update(context, bits, 8);

/* Store state in digest */

/*将最终的结果保存到digest中。ok,终于大功告成了*/ Encode(digest, context->state, 16);

21

密码学课程设计

/* Zeroize sensitive information. */

R_memset((POINTER)context, 0, sizeof(*context)); }

/* MD5 basic transformation. Transforms state based on block. */ /*

对512bits信息(即block缓冲区)进行一次处理,每次处理包括四轮

state[4]:md5结构中的state[4],用于保存对512bits信息加密的中间结果或者最终结果

block[64]:欲加密的512bits信息 */

static void MD5Transform (UINT4 state[4], unsigned char block[64]) {

UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];

Decode(x, block, 64);

/* Round 1 */

FF(a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ FF(d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ FF(c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ FF(b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ FF(a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ FF(d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ FF(c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ FF(b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ FF(a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ FF(d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */

/* Round 2 */

GG(a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ GG(d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ GG(b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ GG(a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */

22

密码学课程设计

GG(b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ GG(a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ GG(c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ GG(b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ GG(d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ GG(c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */

/* Round 3 */

HH(a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ HH(d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ HH(a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ HH(d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ HH(c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ HH(d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ HH(c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ HH(b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ HH(a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ HH(b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */

/* Round 4 */

II(a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ II(d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ II(b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ II(d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ II(b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ II(a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ II(c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ II(a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ II(c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */

23

密码学课程设计

II(b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */

state[0] += a; state[1] += b; state[2] += c; state[3] += d;

/* Zeroize sensitive information. */ R_memset((POINTER)x, 0, sizeof(x)); }

/* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */

/*将4字节的整数copy到字符形式的缓冲区中 output:用于输出的字符缓冲区

input:欲转换的四字节的整数形式的数组

len:output缓冲区的长度,要求是4的整数倍 */

static void Encode(unsigned char *output, UINT4 *input,unsigned int len) {

unsigned int i, j;

for(i = 0, j = 0; j < len; i++, j += 4) {

output[j] = (unsigned char)(input[i] & 0xff);

output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); } }

/* Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. */

/*与上面的函数正好相反,这一个把字符形式的缓冲区中的数据copy到4字节的整数中(即以整数形式保存) output:保存转换出的整数 input:欲转换的字符缓冲区

len:输入的字符缓冲区的长度,要求是4的整数倍 */

static void Decode(UINT4 *output, unsigned char *input,unsigned int len) {

unsigned int i, j;

for(i = 0, j = 0; j < len; i++, j += 4)

output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |

24

密码学课程设计

(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); }

////////////////////////////////////////////////////////////////////////////////

// md5test.cpp : Defines the entry point for the console application. //

#include \#include \

int main(int argc, char* argv[]) {

MD5_CTX md5;

MD5Init(&md5); //初始化用于md5加密的结构

unsigned char encrypt[200]; //存放于加密的信息 unsigned char decrypt[17]; //存放加密后的结果 scanf(\ //输入加密的字符

MD5Update(&md5,encrypt,strlen((char *)encrypt)); //对欲加密的字符进行加密

MD5Final(decrypt,&md5); //获得最终结果

printf(\加密前:%s\\n加密后:\ for(int i=0;i<16;i++)

printf(\

printf(\加密结束!\\n\

return 0; }

2.4 关键算法分析如下: 主循环有四轮(MD4只有三轮),每轮循环都很相似。第一轮进行16次操作。每次操作对a、b、c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量,文本的一个子分组和一个常数。再将所得结果向右环移一个不定的数,并加上a、b、c或d中之一。最后用该结果取代a、b、c或d中之一。 以一下是每次操作中用到的四个非线性函数(每轮一个)。

F(X,Y,Z) =(X&Y)|((~X)&Z) G(X,Y,Z) =(X&Z)|(Y&(~Z))

25

密码学课程设计

密钥密钥扩展明文W[0] ~ W[3]明文轮密钥加变换逆列混淆变换逆S盒变换逆行移位变换最后一轮S盒变换第一轮行移位变换列混淆变换轮密钥加变换W[4] ~ W[7]逆列混淆变换轮密钥加变换逆S盒变换逆行移位变换第()轮Nr-1S盒变换第()轮行移位变换列混淆变换轮密钥加变换W[4(Nr-1)] ~ W[4Nr-1]逆列混淆变换轮密钥加变换逆S盒变换S盒变换最后一轮逆行移位变换行移位变换W[4Nr] ~ W[4(Nr+1)-1]轮密钥加变换轮密钥加变换第一轮Nr-1密文密文加密解密

图 3-1 AES加解密流程图

正向变换:正向字节代换变换就是一个简单的查表操作。AES的S盒由16x16字节组成的矩阵,包含了8位值所能表达256种可能的变换。State中每个字节按照如下方式映射为一个新的字节:字节的高4位作为行值,低4位作为列值,S盒中对应行列的元素作为输出。S是使用定义在GF(28)中的变换值来构成的,可以对付各种已知的可能攻击。

非线性的字节替代,单独处理每个字节:求该字节在有限域GF(28)上的乘法逆,\被映射为自身,即对于α∈GF(28),求β∈GF(28),使得α·β=β·α=1mod(x8+x4+x2+x+1)。

对上一步求得的乘法逆作仿射变换:yi=xi + x(i+4)mod8 + x(i+6)mod8 + x(i+7)mod8 + ci

(其中ci是6310即011000112的第i位),用矩阵表示为

31

密码学课程设计

?y0??1?y1??0????y2??0????y3???0?y4??1????y5??1?y6??1?????y7????11111000??x0??0??x1??1?1111100??????0111110??x2??1??????0011111??x3??0??0001111??x4??0??????1000111??x5??0?1100011??x6??1??????1110001????x7????1??

(2)行移位变换

行位移操作作用于S盒的输出,其中,列的4个行螺旋的左移,即第0行左移0字节,第1行左移1字节,第2行左移2字节,第3行左移3字节,如下图所示。从该图中可以看出,这使得列完全进行了重排,即在移位后的每列中。都包含有未位移前每个列的一个字节。接下来就可以进行列内混合了。

(3)列混淆变换 逐列混合方法: b(x) = (03·x3 + 01·x2 + 01·x + 02)·a(x) mod(x4 + 1)

矩阵表示形式:

?b0??02?b1??01?????b2??01????b3??03030201010103020101??a0??a1?01????03??a2????02??a3?

其中FFmul为有限域GF(28)上的乘法,标准算法应该是循环8次(b与a的每一位相乘,结果相加),但这里只用到最低2位,解密时用到的逆列混淆也只用了低4位,所以在这里高4位的运算是多余的,只计算低4位。 轮密钥加变换

简单来说就是逐字节相加,有限域GF(28)上的加法是模2加法,即异或。

3-2 列混淆流程

(4)密钥扩展

AES加密解密过程中,每一轮都需要一个与输入分组具有相同长度的扩展密钥W[i]的参与。由于外部输入的加密密钥长度有限,所以在算法中要

32

密码学课程设计

一个密钥扩展程序把外部密钥扩展成更长的比特串,以生成各轮的加密和解密密钥。

通过生成器产生Nr+1轮轮密钥,每个轮密钥由Nb个字组成,共有Nb(Nr+1)个字W[i],i=0,1,??,Nb(Nr+1)-1。

图3-3 密钥扩展流程

3.3 实验代码如下: #include #include #include #include using namespace std; #define Nb 4 int Nr=0; int Nk=0; int Nc = 128; char out[32];

unsigned char RoundKey[240],in[16], state[4][4]; unsigned char Key[32];

#define xtime(x) ((x<<1) ^ (((x>>7) & 1) * 0x1b))

#define Multiply(x,y) (((y & 1) * x) ^ ((y>>1 & 1) * xtime(x)) ^ ((y>>2 & 1) * xtime(xtime(x))) ^ ((y>>3 & 1) * xtime(xtime(xtime(x)))) ^ ((y>>4 & 1) * xtime(xtime(xtime(xtime(x))))))

int getSBoxValue(int num) {

int sbox[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,

0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4,

33

密码学课程设计

0x72, 0xc0,

0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,

0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,

0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,

0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,

0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,

0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,

0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,

0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,

0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,

0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,

0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,

0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,

0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,

0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };

return sbox[num]; }

int getSBoxInvert(int num) { int rsbox[256] = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb , 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb , 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e , 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25

34

密码学课程设计

, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 , 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 , 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 , 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b

, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 , 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e , 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b , 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 , 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f , 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef , 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 , 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; return rsbox[num]; }

int Rcon[255] = {

0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,

0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,

0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,

0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,

0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,

0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,

0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,

35

密码学课程设计

0x40, 0x80, 0x1b,

0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,

0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,

0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,

0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,

0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,

0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,

0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,

0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,

0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb };

void KeyExpansion() {

int i,j;

unsigned char temp[4],k; for(i=0;i

RoundKey[i*4]=Key[i*4];

RoundKey[i*4+1]=Key[i*4+1]; RoundKey[i*4+2]=Key[i*4+2]; RoundKey[i*4+3]=Key[i*4+3]; }

while (i < (Nb * (Nr+1))) {

for(j=0;j<4;j++) {

temp[j]=RoundKey[(i-1) * 4 + j]; }

if (i % Nk == 0) { k = temp[0]; temp[0] = temp[1]; temp[1] = temp[2]; temp[2] = temp[3];

36

密码学课程设计

temp[3] = k; temp[0]=getSBoxValue(temp[0]); temp[1]=getSBoxValue(temp[1]); temp[2]=getSBoxValue(temp[2]); temp[3]=getSBoxValue(temp[3]); temp[0] = temp[0] ^ Rcon[i/Nk]; }

else if (Nk > 6 && i % Nk == 4) { temp[0]=getSBoxValue(temp[0]); temp[1]=getSBoxValue(temp[1]); temp[2]=getSBoxValue(temp[2]); temp[3]=getSBoxValue(temp[3]); }

RoundKey[i*4+0] = RoundKey[(i-Nk)*4+0] ^ temp[0]; RoundKey[i*4+1] = RoundKey[(i-Nk)*4+1] ^ temp[1]; RoundKey[i*4+2] = RoundKey[(i-Nk)*4+2] ^ temp[2]; RoundKey[i*4+3] = RoundKey[(i-Nk)*4+3] ^ temp[3]; i++; } }

void AddRoundKey(int round) {

int i,j;

for(i=0;i<4;i++)

for(j=0;j<4;j++)

state[j][i] ^= RoundKey[round * Nb * 4 + i * Nb + j]; }

void InvSubBytes() {

int i,j;

for(i=0;i<4;i++)

for(j=0;j<4;j++)

state[i][j] = getSBoxInvert(state[i][j]); }

void InvShiftRows() {

unsigned char temp;

37

密码学课程设计

temp=state[1][3];

state[1][3]=state[1][2]; state[1][2]=state[1][1]; state[1][1]=state[1][0]; state[1][0]=temp; temp=state[2][0];

state[2][0]=state[2][2]; state[2][2]=temp; temp=state[2][1];

state[2][1]=state[2][3]; state[2][3]=temp; temp=state[3][0];

state[3][0]=state[3][1]; state[3][1]=state[3][2]; state[3][2]=state[3][3]; state[3][3]=temp; }

void InvMixColumns() {

int i;

unsigned char a,b,c,d; for(i=0;i<4;i++) {

a = state[0][i]; b = state[1][i]; c = state[2][i]; d = state[3][i];

state[0][i] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);

state[1][i] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);

state[2][i] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);

state[3][i] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e); } }

void InvCipher() {

38

密码学课程设计

int i,j,round=0; for(i=0;i<4;i++)

for(j=0;j<4;j++)

state[j][i] = in[i*4 + j]; AddRoundKey(Nr);

for(round=Nr-1;round>0;round--) {

InvShiftRows(); InvSubBytes();

AddRoundKey(round); InvMixColumns(); }

InvShiftRows(); InvSubBytes(); AddRoundKey(0); for(i=0;i<4;i++) {

for(j=0;j<4;j++) {

out[i*4+j]=state[j][i];} } }

void SubBytes() {

int i,j;

for(i=0;i<4;i++)

for(j=0;j<4;j++)

state[i][j] = getSBoxValue(state[i][j]); }

void ShiftRows() {

unsigned char temp; temp=state[1][0];

state[1][0]=state[1][1]; state[1][1]=state[1][2]; state[1][2]=state[1][3]; state[1][3]=temp; temp=state[2][0];

state[2][0]=state[2][2]; state[2][2]=temp; temp=state[2][1];

39

密码学课程设计

state[2][1]=state[2][3]; state[2][3]=temp; temp=state[3][0];

state[3][0]=state[3][3]; state[3][3]=state[3][2]; state[3][2]=state[3][1]; state[3][1]=temp; }

#define xtime(x) ((x<<1) ^ (((x>>7) & 1) * 0x1b)) void MixColumns() {

int i;

unsigned char Tmp,Tm,t; for(i=0;i<4;i++) {

t=state[0][i];

Tmp = state[0][i] ^ state[1][i] ^ state[2][i] ^ state[3][i] ;

Tm = state[0][i] ^ state[1][i] ; Tm = xtime(Tm); state[0][i] ^= Tm ^ Tmp ; Tm = state[1][i] ^ state[2][i] ; Tm = xtime(Tm); state[1][i] ^= Tm ^ Tmp ; Tm = state[2][i] ^ state[3][i] ; Tm = xtime(Tm); state[2][i] ^= Tm ^ Tmp ; Tm = state[3][i] ^ t ; Tm = xtime(Tm); state[3][i] ^= Tm ^ Tmp ; } }

void Cipher() {

int i,j,round=0; for(i=0;i<4;i++) for(j=0;j<4;j++)

state[j][i] = in[i*4 + j]; AddRoundKey(0);

for(round=1;round

SubBytes(); ShiftRows(); MixColumns();

AddRoundKey(round); }

SubBytes(); ShiftRows();

AddRoundKey(Nr);

40

本文来源:https://www.bwwdw.com/article/2rdg.html

Top