古典密码学实验
![古典密码学实验](https://img.360docs.net/img07/084cr125cd7yvct1fjv-71.webp)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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
vector
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) {