当前位置:文档之家› 古典密码学实验

古典密码学实验

一、实验背景与目的
通过实现简单的古典密码算法,理解密码学的相关概念如明文(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<iostream>
#include<fstream> //引入文件流头文件
#include<vector> //引入向量
using namespace std;
void main()
{
ifstream in("a.txt");
vector<int> s;
vector<int> 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<<"统计结果如下:"<<endl;
for(int k=0;k<26;++k)
cout<<' '<<char(k+97)<<"出现的概率为:"<<n[k]/sum<<endl;
system("pause");
}
//实验二:用C\C++语言实现仿射变换(Affine)加/解密算法
//其中a, b为密钥,,且gcd(a, 26)=1,0<=a,b<=25
#include<iostream>
#include<fstream>
#include<vector>
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欢迎进入仿射变换加/解密程序"<<endl
<<"0、加密"<<endl
<<"1、解密"<<endl;
int z;
cin>>z;
if(z==0||z==1)
{
cout<<"请输入密钥a和b:(注意:0<=a,b<=25且gcd(a, 26)=1)"<<endl; int a,b;
cin>>a>>b;
if((a<1||a>25)||(b<0||b>25))
cout<<"a,b的输入范围有错!"<<endl;
else
if(gcd(a)==0)
{
cout<<"密钥a有误,与26不互素"<<endl;
goto L;
}
else
{
if(z==0) //加密算法
{
ifstream in("a.txt");
ofstream out("b.txt");
vector<int> s;
for(char x;in>>x; ) //依次读取a.txt中的内容
s.push_back(int(x));
for(int i=0;i<s.size();++i)
{
s[i]=(a*(s[i]-97)+b)%26;
out<<char(s[i]+97);
}
out<<endl;
cout<<"加密成功!密文在‘b.txt’文件"<<endl;
}
else //解密算法
{
ifstream in("b.txt");
ofstream out("a.txt");
vector<int> s;
for(char x;in>>x;)
s.push_back(int(x));
for(int i=0;i<s.size();++i)
{
s[i]=inv(a)*(s[i]-97-b+26)%26;
out<<char(s[i]+97);
}out<<endl;cout<<"解密成功!明文在‘a.txt’文件"<<endl;
}
}
}
else
{
cout<<"所选操作无效!"<<endl;
goto L;
}
system("pause"); }。

相关主题