密码学课程设计论文.docx
《密码学课程设计论文.docx》由会员分享,可在线阅读,更多相关《密码学课程设计论文.docx(28页珍藏版)》请在冰点文库上搜索。
密码学课程设计论文
课程设计
课程名称密码学课程设计
题目名称古典密码算法的实现与分析
学生学院应用数学学院
专业班级07级信息安全2班
学号31070089123107008913
3107008914
学生姓名卜子华陈文龙陈彦生
指导教师李锋
2009年12月07日
广东工业大学课程设计任务书
题目名称
古典密码算法的实现及分析
学生学院
应用数学学院
专业班级
07级信息安全2班
姓名
卜子华陈文龙陈彦生
学号
3107008912、3107008913、3107008914
一、课程设计的内容
运用C语言、C++面向对象、数据结构以及刚学习的密码学等知识,在认真学习古典密码的理论知识之后,通过编程进行各类古典密码的算法的实现,并产生界面友好。
二、课程设计的要求与数据
论文摘要包括,摘要正文和关键词,课程设计正文(绪论(说明做这个课题的意义)、理论部分(相关的理论)、代码的实现部分、总结)
三、课程设计应完成的工作
各类古典密码算法的编写
程序MFC的关联
论文的撰写(目录的自动生成)
四、课程设计进程安排
序号
设计各阶段内容
地点
起止日期
1
查找相关资料
图书馆
11.16-11.16
2
课程设计具体分工及部分算法编写
课室、宿舍
11.17-11.17
3
算法及程序的编写
宿舍
11.18-11.20
4
程序的修改和完善
宿舍
11.21-11.21
5
论文的撰写及总结
宿舍
11.22-11.22
五、应收集的资料及主要参考文献
发出任务书日期:
2009年11月1日
指导教师签名:
计划完成日期:
2009年11月日
基层教学单位责任人签章:
主管院长签章:
论文摘要:
本文主要对古典密码中的移位密码(凯撒密码),仿射密码,维吉利亚(Vigenere)密码以,单表代换密码,置换密码和周期置换密码进行算法设计,最后用C++方法实现友好界面。
通过对这几个古典密码的算法分析,更加系统的掌握其中的原理和应用。
关键词凯撒密码、置换密码、算法、MFC关联、代码
第1章绪论
密码学包括两部分,即密码编码学和密码分析学,这两个部分即对立又统一,正是由于其对立性才促进了密码学的发展。
一个密码系统的安全性只有通过对该系统抵抗当前各类攻击能力的考查和全面分析才能做出定论。
密码体制的安全性分析是一个相当复杂的问题,但有一点是清楚的,那就是掌握现有的分析方法并使用这些方法对相应的体制进行分析以考察其安全强度。
在密码编码体制中,有两种最基本也是最古老的编码体制一直沿用至今,它们是代换密码和置换密码,由于历史悠久并且是现代密码体制的基本组成部分,因而在密码学中占有重要的地位。
古典密码是密码学发展的一个阶段,也是近代密码学产生的渊源,尽管古典密码大多比较简单,一般可用手工或机械方式实现其加密和解密过程,破译也比较简单,目前已经很少采用,但了解它们的设计原理,有助于理解、设计和分析现代密码。
日常生活中,在大多数的情况下,我们不用担心别人偷听,因为即使被人偷听到了他也无法用偷听到的信息做什么坏事。
但当我们谈论某些比较敏感的话题时,被别人偷听到的话可能会产生一些负面的影响,对当事人很不利。
在文字交流中,一些重要的信息,比如重要决定,人事变动和秘密情报等,当事人是不希望别人看到的,但如何进行交流呢?
一个简单的办法就是采用文字编码。
例如,将英文中的每个字母固定地换成它后面第5个字母,A换成F,B换成G,…,V换成A,W换成B,…,最后Z换成E。
字母编码如下表所示:
原文
A
B
C
D
…
V
W
X
Y
Z
密文
F
G
H
I
…
A
B
C
D
E
因此,消息Iloveyou就变成了nqtajdtz,消息有明确的信息,而编码后的字符串却是一串乱码,信息隐藏在其中,达到了保密的效果。
对于古典密码体制而言,我们有如下的约定:
加密解密时忽略空格和标点符号,这可能让人不太适应,但是经过解密后,几乎总是可以正确的还原明文中的这些空缺。
如果保留这些空缺,密文会保持明文的结构特点,为攻击者提供便利。
本文主要是通过对各类型的古典密码进行算法设计,通过编写程序来深层掌握古典密码的算法技术,通过对各类型古典密码进行详细的分析,分工讨论,在实现系统掌握这些密码算法的同时,也对C语言和C++面向对象进行了复习,有效的巩固了以前的知识,也培养了对专业密码学的学习兴趣。
第2章理论部分
代换是古典密码中用到的最基本的处理技巧,它在现代密码学中得到了广泛的应用,内容非常的丰富,人们采用代换密码进行加密时并没有固定的模式。
按照一个明文字母是否总是被一个固定的字母代换进行划分时,代换密码可以分为两大类:
(1)单表代换密码:
对明文消息中出现的同一个字母,在加密时都用同一个固定的字母来代换,不管它出现在什么地方。
移位密码和仿射密码都属于单表代换密码。
(2)多表代换密码:
明文消息中出现的同一个字母,在加密时不是完全被同一个固定的字母代换,而是根据其出现的位置次序,用不同的字母代换,如维吉利亚密码和Playfair密码。
2.1:
移位密码
明文空间P与密文空间C都是26个英文字母的集合,密钥空间K={0,1,2,…,25}。
在实际进行加密解密运算时,把26个字母依次与0,1,2,…,25对应。
因而也可以说P=C=K={0,1,…,25}=Z。
E={e:
Z->Z,e(x)=x+k(mod26)},即对每个K∈Z,相应的加密变换为ek(m)=m+k(mod26),其中m∈Z为明文。
D={d:
Z->Z,d(x)=x-k(mod26)},即对密钥k,解密变换为dk(y)=y-k(mod26),其中y∈Z为密文。
解密之后要把Z中的元素再变换为英文字母。
2.2:
仿射密码
明、密文空间与移位密码相同,密钥空间为K={(k1,k2)|k1,k2∈Z,其中gcd(k1,26=1)}gcd表示两个数的最大公因子,gcd(k1,26)=1,即表示k1还26互素。
对任意的k=(k1,k2)∈K,加密变换为e(m)=k1*m+k2*(mod26).相应的解密变化为d(c)=k1^(-1)*(c-k2)(mod26),其中:
k1*k1^(-1)=1(mod26).
2.3:
维吉利亚密码
该密码有一个参数n。
在加解密时同样把英文字母用数字代替进行运算,并按n个字母一组进行变换。
明、密文空间及密钥空间都是n长的字母串的集合,因此可以表示P=C=K=Z^(26).加密变换如下:
设密钥k=(k1,k2,…,kn),明文P=(m1,m2,…,mn),加密函数为e(p)=(c1,c2,…,cn),其中Ci=(mi+ki)(mod26),i=1,2,…,n。
对密文c=(m1,m2,…,mn),密钥k=(k1,k2,…,kn),解密变换为:
e(c)=(m1,m2,…,mn),其中m1=(c1-k1)(mod26),i=1,2,…,n。
其中mi=(ci-ki)(mod26),i=1,2,…,n。
2.4:
一般的单表代换密码
单表代换密码的原理是:
以26个字母的集合上的一个置换∏为密钥对明文消息中的每个字母依次进行变换,变换的方法是把明文中的每个字母用它在置换∏下的像去替换。
解密时用∏的逆置换进行替换。
可描述为P=C={0,1,2,…,25}=Z,K={∏:
Z->Z|∏是置换}。
密钥∏对应的加密变换e(x)=∏(x),解密变换为d(y)=∏^(-1)(y).前面描述的移位密码和仿射密码都是单表代换密码,而维吉利亚密码不是单表代换密码。
2.5:
列置换密码
置换密码是把明文中各字符的位置次序重新排列来得到密文的一种密码体制。
列置换密码的加密方法如下:
把明文字符以固定的宽度m(分组长度)水平地(按行)写在一张纸上,按1,2,3,…,m的一个置换∏交换列的次序位置,再按垂直方向(按列)读出即得密文。
解密就是就是将密文按照相同的宽度m垂直的写在纸上,按置换∏的逆置换交换列的位置次序,然后水平的读出得到明文,置换∏就是密钥。
2.6:
周期置换密码
周期置换密码是将明文字符按照一定长度m分组,把每组中的字符按1,2,…,m的一个置换∏重排位置次序来得到密文的一种加密方法。
其中的密钥就是置换∏,在∏的描述中包含了分组长度的信息。
解密时,对密文字符按长度m分组,并按∏的逆置换∏^(-1)把每组字符重排位置次序来得到明文。
第3章代码的实现
3.1:
程序主界面:
3.2移位密码:
部分代码实现:
voidkaisa:
:
Onjiami()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
inti;
charb;
this->UpdateData();
if(m_mingwen.IsEmpty())
MessageBox("要加密的文字不能为空!
");
m_jiami=m_mingwen;
intn=m_jiami.GetLength();
for(i=0;i{
b=m_jiami.GetAt(i);
if('a'<=b&&b<='z')
m_jiami.SetAt(i,'a'+(b-'a'+m_k)%26);
else
if('A'<=b&&b<='Z')
m_jiami.SetAt(i,'A'+(b-'A'+m_k)%26);
else
{
m_jiami="";
this->MessageBox("输入明文只能为大、小写字母或空格!
");
}
}
this->UpdateData(false);
}
voidkaisa:
:
Onjiemi()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
this->UpdateData();
inti;
m_jiemi=m_jiami;
intn=m_jiemi.GetLength();
for(i=0;i{
charb=m_jiemi.GetAt(i);
if('a'<=m_jiami.GetAt(i)&&m_jiami.GetAt(i)<='z')
m_jiemi.SetAt(i,'a'+(b-'a'-m_k+26)%26);
if('A'<=b&&b<='Z')
m_jiemi.SetAt(i,'A'+(b-'A'-m_k+26)%26);
}
this->UpdateData(false);
}
voidkaisa:
:
Onclose()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
CDialog:
:
OnOK();
}
3.3仿射密码
部分代码如下:
fangshe:
:
fangshe(CWnd*pParent/*=NULL*/)
:
CDialog(fangshe:
:
IDD,pParent)
{
//{{AFX_DATA_INIT(fangshe)
m_mingwen=_T("");
m_k1=0;
m_k2=0;
m_jiami=_T("");
m_jiemi=_T("");
//}}AFX_DATA_INIT
}
voidfangshe:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(fangshe)
DDX_Text(pDX,IDC_EDIT1,m_mingwen);
DDX_Text(pDX,IDC_EDIT2,m_k1);
DDX_Text(pDX,IDC_EDIT3,m_k2);
DDX_Text(pDX,IDC_EDIT4,m_jiami);
DDX_Text(pDX,IDC_EDIT5,m_jiemi);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(fangshe,CDialog)
//{{AFX_MSG_MAP(fangshe)
ON_BN_CLICKED(IDCANCEL,Onjiami)
ON_BN_CLICKED(IDOK,Onjiemi)
ON_BN_CLICKED(IDC_BUTTON1,Onclose)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//fangshemessagehandlers
intgcd(inta,intb)/*辗转相除法求a,b的最大公因数*/
{
intk=0;
do
{
k=a%b;
a=b;
b=k;
}while(k!
=0);
returna;
}
intNi(inta,intb)/*求a相对于b的逆*/
{
inti=0;
while(a*(++i)%b!
=1);
returni;
}
voidfangshe:
:
Onjiami()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
inti;
this->UpdateData();
if(m_mingwen.IsEmpty())
MessageBox("要加密的文字不能为空!
");
m_jiami=m_mingwen;
intn=m_jiami.GetLength();
charb;
for(i=0;i{
b=m_jiami.GetAt(i);
//if('a'<=b&&b<='z')
if(gcd(m_k1,26)==1)
{
if('a'<=b&&b<='z')
m_jiami.SetAt(i,'a'+(m_k1*(b-'a')+m_k2)%26);
else
if('A'<=b&&b<='Z')
m_jiami.SetAt(i,'A'+(m_k1*(b-'A')+m_k2)%26);
else
if(b=='')
{m_jiami.SetAt(i,NULL);}
else
{
m_jiami="";
this->MessageBox("输入明文只能为大、字母或空格!
");
}
}
else
{
m_jiami="";
this->MessageBox("请输入一个和26互素的正整数作为密钥!
");
}
}
this->UpdateData(false);
}
voidfangshe:
:
Onjiemi()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
this->UpdateData();
inti;
m_jiemi=m_jiami;
intn=m_jiemi.GetLength();
for(i=0;i{
charb=m_jiemi.GetAt(i);
if('a'<=b&&b<='z')
m_jiemi.SetAt(i,'a'+(Ni(m_k1,26)*(b-'a'-m_k2+26))%26);
if('A'<=b&&b<='Z')
m_jiemi.SetAt(i,'A'+(Ni(m_k1,26)*(b-'A'-m_k2+26))%26);
}
this->UpdateData(false);
}
voidfangshe:
:
Onclose()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
CDialog:
:
OnOK();
3.4维吉利亚密码
部分代码:
voidVigenere:
:
OnButton1()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
CDialog:
:
OnOK();
}
voidVigenere:
:
Onjiami()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
inti,j,k;
intpos=0,tag;
this->UpdateData();
if(m_mingwen.IsEmpty())
MessageBox("要加密的文字不能为空!
");
if(m_k.IsEmpty())
MessageBox("密钥不能为空!
");
intn=m_mingwen.GetLength();//求输入内容的长度
intm=m_k.GetLength();//密钥长度
m_jiami=m_mingwen;
for(i=0,j=0;i{
if(m_jiami.GetAt(i)!
='')
{
B[j++]=m_jiami.GetAt(i);
tag=0;
S[pos++]=tag;//遇到空格,S中该位置的元素为0;
}
else
{
tag=1;
S[pos++]=tag;//遇到非空格,S中该位置的元素为1;
}
}
//m_jiami.Remove('');
//j=m_jiami.GetLength();
for(k=0;k{//B[k]=m_jiami.GetAt(k);
A[k%m]=m_k.GetAt(k%m);
if('a'<=B[k]&&B[k]<='z')
{
if('a'<=A[k%m]&&A[k%m]<='z')
m_jiami.SetAt(k,'a'+(B[k]-'a'+A[k%m]-'a')%26);
else
if('A'<=B[k%m]&&A[k%m]<='Z')
m_jiami.SetAt(k,'a'+(B[k]-'a'+A[k%m]-'A')%26);
}
else
if('A'<=B[k]&&B[k]<='Z')
{
if('A'<=A[k%m]&&A[k%m]<='Z')
m_jiami.SetAt(k,'A'+(B[k]-'A'+A[k%m]-'A')%26);
else
if('a'<=A[k%m]&&A[k%m]<='z')
m_jiami.SetAt(k,'A'+(B[k]-'A'+A[k%m]-'a')%26);
}
else
{
m_jiami="";
this->MessageBox("输入明文只能为大、小写字母或空格!
");
}
}
for(k=j;km_jiami.SetAt(k,'');
this->UpdateData(false);
}
voidVigenere:
:
Onjiemi()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
inti;
this->UpdateData();
intn=m_jiami.GetLength();
m_jiemi=m_jiami;
intm=m_k.GetLength();
for(i=0;i{
B[i]=m_jiemi.GetAt(i);
A[i%m]=m_k.GetAt(i%m);
if('a'<=B[i]&&A[i]<='z')
{
if('a'<=A[i%m]&&A[i%m]<='z')
m_jiemi.SetAt(i,'a'+(B[i]-'a'-A[i%m]+'a'+26)%26);
else
if('A'<=B[i%m]&&A[i%m]<='Z')
m_jiemi.SetAt(i,'a'+(B[i]-'a'-A[i%m]+'A'+26)%26);
}
else
if('A'<=B[i]&&B[i]<='Z')
{
if('A'<=A[i%m]&&A[i%m]<='Z')
m_jiemi.SetAt(i,'A'+(B[i]-'A'-A[i%m]+'A'+26)%26);
else
if('a'<=A[i%m]&&A[i%m]<='z')
m_jiemi.SetAt(i,'A'+(B[i]-'A'-A[i%m]+'a'+26)%26);
}
}
for(intt=0;t{
if(S[t]==1)//数组S中第t个元素为1,则在前面解密后的内容中的该位置插入空格,已恢复明文中的空格。
{
for(intr=n-2;r>=t;r--)
m_jiemi.SetAt(r+1,m_jiemi.GetAt(r));
m_jiemi.SetAt(t,'');
}
}
this->UpdateData(false);
}
3.5单表代换密码
部分代码:
charstr1[]="abcdefghijklmnopqrstuvwxyz";//原字母表。
charT[27];
voidsingle:
:
OnButton1()
{
//TODO:
Addyourcontrolnotificationhandlercodehere
CDialog:
:
OnOK();
}
voidsingle:
:
Ondhb()
{
//TODO:
Addyourcontrolnotificationhandle