古典密码学实验

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、实验背景与目的

通过实现简单的古典密码算法,理解密码学的相关概念如明文(plaintext)、密文(ciphertext)、加密密钥(encryption key)、解密密钥(decryption key)、加密算法(encryption algorithm)、解密算法(decryption algorithm)等。

二、实验环境

Visual C++6.0

三、实验内容

(1)用C\C++语言实现仿射变换(Affine)加/解密算法;2)

(2)用C\C++语言实现统计26个英文字母出现的频率的程序;

(3)利用仿射变换加/解密程序对一段较长的英文文章进行加密,再利用统计

软件对明文和密文中字母出现的频率进行统计并作对比,观察有什么规

律。

其中a, b为密钥,

25

,

0≤

≤b

a

,且gcd(a, 26)=1

实验要求:加/解密程序对任意满足条件的a、b都能够处理。仿射变换:

加密:

()26

mod

,

b

am

m

E

c

b

a

+

=

=

解密:

()()26

mod

1

,

b

c

a

c

D

m

b

a

-

=

=-

四、实验原理

一个仿射变换对应于一个矩阵和一个向量的乘法,而仿射变换的复合对应于普通的矩阵乘法,只要加入一个额外的行到矩阵的底下,这一行全部是0除了最右边是一个1,而列向量的底下要加上一个1。仿射变换原理在基于MQ问题的多变元公钥密码中,公钥一般是方程组,但是这种没有处理的方程组很容易受到插值法的攻击,例如:首先在q元有限域上选取个变量以及个变量。构造方程组:这里面公钥信息方程组就是:其中是明文信息,而则是密文。可以看出这样的公钥信息很容易受到插值法的攻击,下面使用仿射将

明文信息进行隐藏。先选取一个可逆矩阵,然后进行以下变换:其中是一个可逆矩阵,这样变化以后就可以将转化成以为变量的方程组.

在加密解密程序中,需要对明文进行仿射变换,但是要对大小写做判断,并且处理空格,逗号,等特殊符号。

五、实验结果分析

如图为统计26个英文字母在文章中的概率

如图为加密解密算法

密文如下

六、实验心得

在第一次的密码学上机实验中,我见到并学到了一系列的密码学知识,同时也掌握了如何用不同的方法生成全排序。在我们整个实验过程中,我体会到了许多,也学到了许多。

本次实验,我对擦靠的两个程序都做了大量分析,虽然中途也出了不少的问题,使用了

不正确的程序代码导致出现了很大的错误,甚至程序半天无法相应。但最终都通过同学老的帮助得以解决,原因是我的随机函数多次被调用,导致程序变慢。我希望以本次实验为一个新的起点,从一点一滴出发,认真扎实的学习基本密码学技术,逐渐培养自己的密码学技术能力,愈做愈好。

七、实验附件

//实验一:统计26个英文字母出现的频率的程序

#include

#include //引入文件流头文件

#include //引入向量

using namespace std;

void main()

{

ifstream in("a.txt");

vector s;

vector n(26,0);

for(int i=0;i<26;++i)

s.push_back(97+i); //将97+i依次推入N数组中

for(char x;in>>x; ) //依次读取文件中的内容到X

for(int i=0;i<26;++i)

if(int(x)==s[i]){ //进行判断

n[i]++;}

float sum=0; //注意不能是整型

for(int j=0;j<26;++j)

sum+=n[j]; //统计总字数

cout<<"统计结果如下:"<

for(int k=0;k<26;++k)

cout<<' '<

system("pause");

}

//实验二:用C\C++语言实现仿射变换(Affine)加/解密算法

//其中a, b为密钥,,且gcd(a, 26)=1,0<=a,b<=25

#include

#include

#include

using namespace std;

bool gcd(int a) //判断两个数是不是互素

{

int f=26,g,r;

g=a;

do{ //辗转相除法

r=f%g;

f=g;

g=r;

}while(r);

if(f==1)

return 1; //互素

else

return 0; //不互素

}

int inv(int a) //求逆元

{

int x,i;

for(i=1;i<=30;++i)

if((26*i+1)%a==0) //若满足26.(i)-1= 1 mod a 则逆元成立

{

x=(26*i+1)/a;

break;

}

return x;

}

void main()

{

L:

cout<<"/r/r欢迎进入仿射变换加/解密程序"<

<<"0、加密"<

<<"1、解密"<

int z;

cin>>z;

if(z==0||z==1)

{

相关文档
最新文档