密码学课程设计报告5

密码学课程设计报告5
密码学课程设计报告5

密码学课程设计

班级:

姓名:

学号:

指导教师:

2011.6

目录

密码学课程设计 (1)

1.实验一实现一个多表古典加密和解密程序 (1)

1.1实验目的 (1)

1.2实验要求 (1)

1.3实验内容 (1)

1.4古典加密方法 (1)

1.5 程序代码 (1)

1.6 结果分析 (3)

1.7 实验总结 (3)

2.实验二DES算法的实现 (3)

2.1实验目的 (3)

2.2实验要求 (4)

2.3实验内容 (4)

2.4 DES对称加密算法 (4)

2.5 程序代码 (5)

2.6结果分析 (8)

2.7实验总结 (8)

3.实验三实现一个大素数生成算法 (9)

3.1实验目的 (9)

3.2实验要求 (9)

3.3实验内容 (9)

3.4 Miller-Rabin素性测试法 (9)

3.5 程序代码 (9)

3.6 结果分析 (10)

3.7 实验总结 (11)

4. 结束语 (11)

1.实验一实现一个多表古典加密和解密程序

1.1实验目的

掌握多表古典加密方法。

1.2实验要求

能用高级语言实现古典加密方法。

1.3实验内容

多表古典加密方法主要有Playfair体制、Vigenere体制、Beaufor体制、Vernam体制和Hill体制,用高级语言实现其中一种体制的加密和解密算法。

1.4古典加密方法

古典加密方法分为单表加密和多表加密。古典密码编码方法有置换,代替,加法。把明文中的字母重新排列,字母本身不变,但其位置改变了,这样编成的密码称为置换密码。

最简单的置换密码是把明文中的字母顺序倒过来,然后截成固定长度的字母组作为密文。乘积和迭代是多种加密方法混合使用,对一个加密函数多次迭代。

单表代替密码的安全性不高,一个原因是一个明文字母只由一个密文字母代替。构造多个密文字母表,在密钥的控制下用相应密文字母表中的一个字母来代替明文字母表中的一个字母。一个明文字母有多种代替。 Vigenere密码是著名的多表代替密码。所以本次试验我选择做的就是 Vigenere密码。

1.5 程序代码

#include

#include

#include

#define MAX_LEN 1024

#define LETTERS 26

void encrypt_vigenere(char* plain, char* key, char* cipher)

int max = strlen(plain)-1,

d = strlen(key)-1,

i;

for(i=0;i

cipher[i] = 'a'+(plain[i] -'a' + key[i % d] - 'a'+ LETTERS) % LETTERS; //adding LETTERS to avoid the result is negative

cipher[i] = '\0';

}

void decrypt_vigenere(char* cipher, char* key, char* plain)

{

int max = strlen(cipher),

d = strlen(key)-1,

i;

for(i=0;i

plain[i] ='a'+(cipher[i]-'a'-(key[i % d] - 'a')+LETTERS) % LETTERS; plain[i] = '\0';

}

void main()

{

char cipher[MAX_LEN],key[MAX_LEN],plain[MAX_LEN];

printf("--> Please input the key: \n");

fgets(key,sizeof(key),stdin);

printf("\n--> Please input the plain text: \n");

fgets(plain,sizeof(plain),stdin);

encrypt_vigenere(plain,key,cipher);

printf("\n--> The cipher text is : \n");

printf("%s\n",cipher);

decrypt_vigenere(cipher, key, plain);

printf("\n-->The original message is: \n");

printf("%s\n",plain);

}

1.6 结果分析

首先在程序执行时的提示下,输入密钥,接下来输入要加密明文,程序执行,可以产生加密后的密文,并自动解密出原来的明文。顺利执行加密和解密过程。

1.7 实验总结

古典多表密码有多种体质,这次试验我选择的是Vigenere体制。经过对加密算法的实现,我对古典加密算法的模式,过程和原理有了更深入的了解。

多表古典密码通过构造多个对应明文的密文字母表,在密钥的控制下使用相应的密文字母表中的某个字母来代替明文字母表中的一个字母。达到隐藏明文的目的。解密的时候对这个过程进行逆操作,得到明文。一个明文字母有多种代替。而 Vigenere密码就是著名的多表代替密码。

而且通过编码,又练习了我C++操作的水平。

2.实验二DES算法的实现

2.1实验目的

握分组加密算法的设计与实现方法。

2.2实验要求

用高级语言实现实现DES加密和解密算法。

2.3实验内容

DES是由初始变换、乘积变换和逆初始变换构成,乘积变换是DES算法的核心。首先用代码实现这几个变换,然后组合成DES加密算法。由于DES解密算法与加密算法相同只是子密钥使用次序不同,因此可简单地由加密算法实现解密算法。

2.4 DES对称加密算法

对称加密算法有时又叫做传统密码算法,加密密钥可以从解密密钥中推导出来,解密密钥也可以从加密密钥中推导出来。在大多数的对称算法中,加密密钥和解密密钥是相同的,因此也成为秘密密钥算法或者单密钥算法。它要求发送发和接收方在安全通信之前先商定一个密钥。对称算法的安全性依赖于密钥,所以密钥的保密性对通信至关重要。对称加密算法主要有分组加密和流加密两类。分组加密是指将明文分成固定商都的组,用同一密钥分别对每一组加密,输出固定长度的密文,典型代表:DES、3DES、IDEA。

DES的加密流程:

64位明文

64位密文

DES的加密过程可分为加密处理,加密变换和子密钥生成几个部分组成。

1.加密处理过程

(1)初始变换。加密处理首先要对64位的明文按表1所示的初始换位表IP 进行变换。表中的数值表示输入位被置换后的新位置。例如输入的第58位,在输出的时候被置换到第1位;输入的是第7位,在输出时被置换到第64位。

(2)加密处理。上述换位处理的输出,中间要经过16轮加密变换。初始换位的64位的输出作为下一次的输入,将64位分为左、右两个32位,分别记为L0和R0,从L0、R0到L16、R16,共进行16轮加密变换。其中,经过n轮处理后的点左右32位分别为Ln和Rn,则可做如下定义:

Ln=Rn-1

Rn=Ln-1

其中,kn是向第n轮输入的48位的子密钥,Ln-1和Rn-1分别是第n-1轮的输出,f是Mangler函数。

(3)最后换位。进行16轮的加密变换之后,将L16和R16合成64位的数据,再按照表2所示的最后换位表进行IP-1的换位,得到64位的密文,这就是DES 算法加密的结果。

2.加密变换过程

通过重复某些位将32位的右半部分按照扩展表3扩展换位表扩展为48位,而56位的密钥先移位然后通过选择其中的某些位减少至48位,48位的右半部分通过异或操作和48位的密钥结合,并分成6位的8个分组,通过8个S-盒将这48位替代成新的32位数据,再将其置换一次。这些S-盒输入6位,输出4位。

3.子密钥生成过程

钥通常表示为64位的自然数,首先通过压缩换位PC-1去掉每个字节的第8位,用作奇偶校验,因此,密钥去掉第8、16、24……64位减至56位,所以实际密钥长度为56位,而每轮要生成48位的子密钥。

4.解密处理过程

从密文到明文的解密过程可采用与加密完全相同的算法。不过解密要用加密的逆变换,就是把上面的最后换位表和初始换位表完全倒过来变换。这里不再赘述。

2.5 程序代码

由于代码过长,此处只列出部分关键代码。

void CDES::EncryptKey(char *key){

printf("\n原始密钥: %s",key);

m_dwlKey=ProcessByte((unsigned char*)key,TRUE);

// PrintBit(m_dwlKey);

m_dwlKey=PermuteTable(m_dwlKey,dwlKey_PC_1,56);

// PrintBit(m_dwlKey);

Generate_K();

// printf("\n******************************************\n"); }

unsigned char * CDES::EncryptData(unsigned char *block){

unsigned char *EncrytedData=new unsigned char(15);

int i;

printf("\n原始数据: %s\n",block);

m_dwlData=ProcessByte(block,0);

// PrintBit(m_dwlData);

m_dwlData=PermuteTable(m_dwlData,dwlData_IP,64); EncryptKernel();

// PrintBit(m_dwlData);

DWORDLONG bit6=m_dwlData;

for( i=0;i<11;i++){

EncrytedData[7-i]=(unsigned char)(bit6&0x3f)+46;

bit6>>=6;

}

EncrytedData[11]='\0';

printf("\n加密之后: %s",EncrytedData);

for( i=0;i<8;i++){

EncrytedData[7-i]=(unsigned char)(m_dwlData&0xff);

m_dwlData>>=8;

}

EncrytedData[8]='\0';

return EncrytedData;

}

void CDES::EncryptKernel(void){

int i=1;

DWORDLONG L[17],R[17],B[9],EK,PSB;

L[0]=m_dwlData>>32;

R[0]=m_dwlData&0xffffffff;

for(i=1;i<=16;i++){

L[i]=R[i-1];

R[i-1]=PermuteTable(R[i-1],dwlData_Expansion,48); //Expansion R

EK=R[i-1]^m_dwl_K[i]; //E Permutation

PSB=Generate_B(EK,B); //P Permutation

R[i]=L[i-1]^PSB;

}

R[16]<<=32;

m_dwlData=R[16]|L[16];

m_dwlData=PermuteTable(m_dwlData,dwlData_FP,64);

}

unsigned char* CDES::DescryptData(unsigned char *desData){

int i=1;

unsigned char *DescryptedData=new unsigned char(15); DWORDLONG L[17],R[17],B[9],EK,PSB;

DWORDLONG dataPara;

dataPara=ProcessByte(desData,0);

dataPara=PermuteTable(dataPara,dwlData_IP,64);

R[16]=dataPara>>32;

L[16]=dataPara&0xffffffff;

for(i=16;i>=1;i--){

R[i-1]=L[i];

L[i]=PermuteTable(L[i],dwlData_Expansion,48); //Expansion L EK=L[i]^m_dwl_K[i]; //E Permutation

PSB=Generate_B(EK,B); //P Permutation

L[i-1]=R[i]^PSB;

}

L[0]<<=32;

dataPara=L[0]|R[0];

dataPara=PermuteTable(dataPara,dwlData_FP,64);

// PrintBit(dataPara);

for(i=0;i<8;i++){

DescryptedData[7-i]=(unsigned char)(dataPara&0xff); dataPara>>=8;

}

DescryptedData[8]='\0';

printf("\n加密之后: %s\n",DescryptedData);

return DescryptedData;

}

2.6结果分析

代码通过des分组密码,对明文顺利进行了加密和解密。

2.7实验总结

通过本次试验对DES加密算法的实现,我熟悉了分组密码的工作模式和流程,对其解密过程也有了更清楚的了解。

DES算法是通过s盒与p盒来实现对明文的加密,S盒和P盒的实现使加密算法比较唱。编程实现的时候,首先要了解每个部分各个函数的作用,然后按顺序进行实现,最后得到完整的算法。

通过试验增加了我对DES加密算法的认识,还锻炼了我动手实现代码的能力。

3.实验三实现一个大素数生成算法

3.1实验目的

进一步掌握大素数分解的一般原理和实现方法。

3.2实验要求

能用间接方法实现大素数分解。

3.3实验内容

用代码实现Solovay-Strassen素性测试法或Miller-Rabin素性测试法。

3.4 Miller-Rabin素性测试法

米勒和拉宾的素性测试方法是在费马定理的基础上进行研究的。新的测试基于下面的定理:如果p是素数,x是小于p的正整数,且x^2 mod p = 1,那么要么x=1,要么x=p-1。这是显然的,因为x^2 mod p = 1相当于p能整除x^2-1,也即p能整除(x+1)(x-1)。由于p是素数,那么只可能是x-1能被p整除(此时x=1)或x+1能被p整除(此时x =p-1)。

其基本方法是不断地提取指数n-1中的因子2,把n-1表示成d*2^r(其中d是一个奇数)。那么我们需要计算的东西就变成了a的d*2^r次方除以n的余数。于是,a^(d * 2^(r-1))要么等于1,要么等于n-1。如果a^(d * 2^(r-1))等于1,定理继续适用于a^(d * 2^(r-2)),这样不断开方开下去,直到对于某个i满足a^(d * 2^i) mod n = n-1或者最后指数中的2用完了得到的a^d mod n=1或n-1。

Miller-Rabin算法是一个RP算法。RP是时间复杂度的一种,主要针对判定性问题。一个算法是RP算法表明它可以在多项式的时间里完成,对于答案为否定的情形能够准确做出判断,但同时它也有可能把对的判成错的(错误概率不能超过1/2)。RP算法是基于随机化的,因此多次运行该算法可以降低错误率。

3.5 程序代码

关键部分:

function pow( a, d, n:longint ):longint;

begin

if d=0 then exit(1)

else if d=1 then exit(a)

else if d and 1=0 then exit( pow( a*a mod n, d div 2, n) mod n)

else exit( (pow( a*a mod n, d div 2, n) * a) mod n);

end;

function IsPrime( a,n:longint ):boolean;

var

d,t:longint;

begin

if n=2 then exit(true);

if (n=1) or (n and 1=0) then exit(false);

d:=n-1;

while d and 1=0 do d:=d shr 1;

t:=pow( a, d, n );

while ( d<>n-1 ) and ( t<>1 ) and ( t<>n-1 ) do begin

t:=(t * t)mod n;

d:=d shl 1;

end;

exit( (t=n-1) or (d and 1=1) );

end;

3.6 结果分析

程序顺利运行,进行大素数的生成。

3.7 实验总结

通过试验实现大素数的生成,我深入了解了生成大整数的原理和过程。

试验中用到的方法是米勒—拉宾大素数生成算法模式,这两位的算法是建立在费马定理的基础上的,从而让我熟悉了这一系列的定理,并了解了科学发展的过程。

通过使用C++实现代码,我再次锻炼了将想法通过代码来实现的能力。

4.结束语

长达半个学期的密码学课程设计终于要到一段落,想想每周六早上早早起床来实验室边学习边写代码,真实不容易,但是回头来看看自己的收获,这些都是值得的。

首先是在密码学方面,通过上课学到的东西,只看看老师的演示是不足以让我们理解加密算法的深入原理的。在做实验的时候,我通过回头看上课老师讲过的课件,并且加上C++的一些书籍,在网上查看别人写的代码,加以学习和改进,当自己亲手实现了一个个密码算法,才能真正学到这些算法的精髓所在。

其次,是C++的学习方面。通过课程设计,锻炼了自己在知道某一个算法的原理的情况下,自己动手来实现这个算法的能力。虽然期间有很多困难,不知道从何下手,但通过在图书馆借的书和上网搜索解决办法,我终于克服了一个个困难,完成了课程设计的任务。

通过课程设计,我对密码学学到的东西有了一个更好的了解,也感觉到密码学的深奥和有趣,今后我一定要继续对密码学对C++的学习。

相关文档
最新文档