密码学报告 本文关键词:密码学,报告
密码学报告 本文简介:中国地质大学计算机学院192103—01唐乾学号:20101000214班级:192103—01学生姓名:唐乾指导教师:任伟日期:2012年12月25日题号:实验一、二、三、RSA1预期目标在充分理解古典密码加密体制概念和原理的基础上,用MicrosoftVisualC++6.0实现古典密码加密与解
密码学报告 本文内容:
中国地质大学
计算机学院
192103—01
唐乾
学
号:
20101000214
班
级:
192103—01
学生姓名:
唐乾
指导教师:
任伟
日
期:
2012年12月25日
题
号:
实验一、二、三、RSA
1
预期目标
在充分理解古典密码加密体制概念和原理的基础上,用Microsoft
Visual
C++
6.0实现古典密码加密与解密,演示公钥与密钥的生成及加密与解密的过程。
2
系统分析
2.1
仿射密码:
加法密码和乘法密码结合就构成仿射密码,仿射密码的加密和解密算法是:
C=
Ek(m)=(k1m+k2)
mod
n
M=
Dk(c)=k1(c-
k2)
mod
n
仿射密码具有可逆性的条件是gcd(k,n)=1。当k1=1时,仿射密码变为加法密码,当k2=0时,仿射密码变为乘法密码。
仿射密码中的密钥空间的大小为nφ(n),当n为26字母,φ(n)=12,因此仿射密码的密钥空间为12×26
=
312。
2.2
Playfair密码:
它依据一个5*5的正方形组成的密码表来编写,密码表里排列有25个字母。如果一种语言字母超过25个,可以去掉使用频率最少的一个。如,法语一般去掉w或k,德语则是把i和j合起来当成一个字母看待。英语中z使用最少,可以去掉它。第一步是编制密码表。在这个5*5的密码表中,共有5行5列字母。第一列(或第一行)是密钥,其余按照字母顺序。密钥是一个单词或词组,若有重复字母,可将后面重复的字母去掉。当然也要把使用频率最少的字母去掉。如:密钥是Live
and
learn,去掉后则为liveandr。如果密钥过长可占用第二列或行。
如密钥crazy
dog,可编制成
第二步整理明文。将明文每两个字母组成一对。如果成对后有两个相同字母紧挨或最后一个字母是单个的,就插入一个字母X。如,communist,应成为co,mx,mu,ni,st。最后编写密文。对明文加密规则如下:1
若p1
p2在同一行,对应密文c1
c2分别是紧靠p1
p2
右端的字母。其中第一列被看做是最后一列的右方。如,按照前表,ct对应oc
2
若p1
p2在同一列,对应密文c1
c2分别是紧靠p1
p2
下方的字母。其中第一行被看做是最后一行的下方。3
若p1
p2不在同一行,不在同一列,则c1
c2是由p1
p2确定的矩形的其他两角的字母(至于横向替换还是纵向替换要事先约好,或自行尝试)。如,按照前表,wh对应tk或kt。如,依照上表,明文where
there
is
life,there
is
hope。可先整理为wh
er
et
he
re
is
li
fe
th
er
ei
sh
op
ex
然后密文为:kt
yg
wo
ok
gy
nl
hj
of
cm
yg
kg
lm
mb
wf
将密文变成大写,然后几个字母一组排列。
Playfair解密算法首先将密钥填写在一个5*5的矩阵中(去出重复字母和字母z),矩阵中其它未用到的字母按顺序填在矩阵剩余位置中,根据替换矩阵由密文得到明文。对密文解密规则如下:1
若c1
c2在同一行,对应明文p1
p2分别是紧靠c1
c2
左端的字母。其中最后一列被看做是第一列的左方。2
若c1
c2在同一列,对应明文p1
p2分别是紧靠c1
c2
上方的字母。其中最后一行被看做是第一行的上方。3
若c1
c2不在同一行,不在同一列,则p1
p2是由c1
c2确定的矩形的其他两角的字母。
2.3
Vigenere密码:
给定一个任意密钥k,其中k=(k1,k2,k3
…Kn)并且ki∈Z26(1≦i≦n);任意明文P=(P1,P2,P3…Pm),并且Pj∈Z26(1≦j≦m);将加密后得到的密文表示为c=(c1,c2……cm)并且cj∈(1≦j≦m)。
这样,我们中以定义如下所示的加密操作Eki:
Cj=Eki(Pj)(其中Eki(p)j→Pj+Ki(mod
26))
还可以定义如下所示的解密操作:
Pj=Dki(cj)(其中Dki(c):cj→cj-Ki(mod
26))
2.4
希尔密码:
每个字母当作26进制数字:A=0,B=1,C=2.
一串字母当成n维向量,跟一个n×n的矩阵相乘,再将得出的结果模26。注意用作加密的矩阵(即密匙)在/mathbb_^n必须是可逆的,否则就不可能译码。只有矩阵的行列式和26互质,才是可逆的。
设d是一正整数,定义。Hill
cipher的主要思想是利用线性变换方法,不同的是这种变换是在上运算。例如:设d=2,每个明文单元使用
来表示,同样密文单元用
表示,具体的加密中,将被表示为
的线性组合。如:利用线性代数的知识,可得这个运算在
上进行,即mod26,密钥K一般取一个m*m的矩阵。
希尔密码是基于矩阵的线性变换,希尔密码相对于前面介绍的移位密码以及放射密码而言,其最大的好处就是隐藏了字符的频率信息,使得传统的通过字频来破译密文的方法失效。
线性代数中的逆矩阵:在线性代数中,大家都知道,对于一个n阶矩阵
M,如果存在一个n阶矩阵N,使得
M
N
=
E(其中:E为n阶单位矩阵),则称矩阵
N
为矩阵
M
的逆矩阵,并记为
M^-1.比如
2阶矩阵
M
=
[3,6],则很容易得知其逆矩阵:[2,7]M^-1
=
[7/9,-2/3]
[-2/9,1/3]
。关于这个逆矩阵是如何计算出的,通常的有两种方法:一是使用伴随矩阵,通过计算行列式得到。所用公式为:
M^-1
=
M^*
/
D
。(其中M^*为M的伴随矩阵,D为M的行列式的值)二是通过增广矩阵,在M右侧附加一个n阶单位矩阵,再通过初等变换将增广矩阵的左侧变换为一个n阶单位矩阵,这时右侧便是所求的逆矩阵。
3
源代码
#include
“Encryption.h“HGLOBAL
Temp;
int
WINAPI
WinMain(
HINSTANCE
hInstance,HINSTANCE
hPrevInstance,LPSTR
lpCmdLine,int
nShowCmd
)
{
DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,DLGPROC
(DlgP),LPARAM(hInstance));
return
0;
}
BOOL
CALLBACK
DlgP(HWND
hWnd,UINT
wMessage,WPARAM
wParam,LPARAM
lParam)
{
HICON
hIcon;
HWND
hEdit;
switch
(wMessage)
{
case
WM_COMMAND:
switch
(LOWORD(wParam)
)
{
case
IDC_OPEN:
OpenDlg(hWnd);
return
TRUE;
case
ID_M_AFF_EN:
//get
parament
if
(Temp
==
NULL)
{
return
TRUE;
}
else
{
if(Encryption(hWnd,(TCHAR*)Temp))
{
hEdit
=
GetDlgItem(hWnd,IDC_EDIT);
SetWindowText(hEdit,(TCHAR*)Temp);
}
GlobalFree(Temp);
return
TRUE;
}
case
ID_M_AFF_DE:
if
(Temp
==
NULL)
{
return
TRUE;
}
else
{
Decryption(hWnd,(TCHAR*)Temp);
hEdit
=
GetDlgItem(hWnd,IDC_EDIT);
SetWindowText(hEdit,(TCHAR*)Temp);
GlobalFree(Temp);
return
TRUE;
}
case
ID_M_HILL_EN:
if
(Temp
==
NULL)
{
return
TRUE;
}
else
{
if(Hi_Encryption((TCHAR*)Temp,hWnd))
{
hEdit
=
GetDlgItem(hWnd,IDC_EDIT);
SetWindowText(hEdit,(TCHAR*)Temp);
}
GlobalFree(Temp);
return
TRUE;
}
case
ID_M_HILL_DE:
if
(Temp
==
NULL)
{
return
TRUE;
}
else
{
Hi_Decryption((TCHAR*)Temp,hWnd);
GlobalFree(Temp);
return
TRUE;
}
return
TRUE;
case
ID_M_PLAY_EN:
if
(Temp
==
NULL)
{
return
TRUE;
}
else
{
Play_Encryption((TCHAR*)Temp,hWnd);
GlobalFree(Temp);
}
return
TRUE;
case
ID_M_PLAY_DE:
if
(Temp
==
NULL)
{
return
TRUE;
}
else
{
Play_Decryption((TCHAR*)Temp,hWnd);
GlobalFree(Temp);
}
return
TRUE;
case
ID_M_VI_EN:
if
(Temp
==
NULL)
{
return
TRUE;
}
else
{
if(Vi_Encryption((TCHAR*)Temp,hWnd))
{
hEdit
=
GetDlgItem(hWnd,IDC_EDIT);
SetWindowText(hEdit,(TCHAR*)Temp);
}
GlobalFree(Temp);
return
TRUE;
}
return
TRUE;
case
ID_M_VI_DE:
if
(Temp
==
NULL)
{
return
TRUE;
}
else
{
Vi_Decryption((TCHAR*)Temp,hWnd);
hEdit
=
GetDlgItem(hWnd,IDC_EDIT);
SetWindowText(hEdit,(TCHAR*)Temp);
GlobalFree(Temp);
return
TRUE;
}
return
TRUE;
default:
return
FALSE;
}
case
WM_INITDIALOG:
hIcon
=
LoadIcon(HINSTANCE(lParam),MAKEINTRESOURCE(IDI_ICON1));
SendMessage(hWnd,WM_SETICON,ICON_BIG,LPARAM(hIcon));
return
TRUE;
case
WM_CLOSE:
EndDialog(hWnd,NULL);
return
TRUE;
default:
return
FALSE;
}
}
void
OpenDlg(HWND
hWnd)
{
OPENFILENAME
openfile;
HANDLE
hFile;
DWORD
FileSize;
DWORD
ByteRead;
static
TCHAR
fileBuf[MAX_PATH];
static
TCHAR
FileTitle[MAX_PATH];
static
TCHAR
FileFilter[]=
TEXT(“Text
Files(*.txt)/0*.txt/0/0“);
RtlZeroMemory(
openfile.lStructSize
=
sizeof(OPENFILENAME);
openfile.hwndOwner
=
hWnd;
openfile.Flags
=
OFN_EXPLORER;
openfile.lpstrFile
=
fileBuf;
openfile.lpstrFilter
=FileFilter;
openfile.nMaxFile
=
MAX_PATH;
openfile.nMaxFileTitle
=
MAX_PATH;
openfile.nMaxFileTitle
=MAX_PATH;
if(GetOpenFileName(
FileSize
=
GetFileSize(hFile,NULL);
Temp
=
GlobalAlloc(GMEM_FIXED
|
GMEM_ZEROINIT,FileSize+1);
if
(Temp
==
NULL)
{
MessageBox(NULL,TEXT(“Memory
allocate
error!“),TEXT(“oh,no“),MB_OK
|MB_ICONERROR);
return
;
}
if(!ReadFile(hFile,Temp,FileSize,return;
}
SetWindowText(GetDlgItem(hWnd,IDC_PATH),openfile.lpstrFile);
CloseHandle(hFile);
}
else
return;
}
4
测试数据及结果
运行效果如下图:
图1
1
预期目标
在充分理解ELGamal加密、签名体制概念和原理的基础上,用Microsoft
Visual
C++
6.0实现ELGamal加密与签名,演示ELGamal加密与签名过程。
2
系统分析
2.1.1
计算体系参数
随机素数p,用户的私有密钥x,g和x计算得到的整数y,消息m,随机数k。
2.1.2
计算密钥
公开密钥(p,g,y),私有密钥x
2.1.3
对文件签名
任何一个给定的消息都可以产生多个有效的ELGamal签名。
2.1.4
验证签名文件
验证算法能够将上述多个ELGamal签名中的任何一个当作可信的签名接受。
2.1.5
密钥对产生办法
首先选择一个素数p,两个随机数,g
和x,g,x
#include
#include
int
a,b;
int
prime_number_p();
int
random(int);
int
m_develop(int
);
/*---------------------------------*/
int
prime(int
p)
{int
i,j;
for(i=2;i=n;p--)
{if(prime(p)==1)
return
p;
}
}//求出n,m之间的最大素数
/*--------------------------------*/
int
prime_number_p()
{
int
p,m,n;
cout>n;
cout>m;
p=prime_number_max(n,m);
if(p==0)
{
coutb)
{
s[0]=a;
s[1]=b;
}
else
{
s[0]=a;
s[1]=b;
}
for(int
i=1;i>m;
if
(m>p)
{
cout>name;
x=p+1;
while(x>=p)
{cout>x;
if(x>=p)
cout>i;
if(i==0)
exit(0);
else
goto
jj;
}
4
测试数据及结果
大素数p的产生和g的产生
用户名以及密钥x,和公钥y的生成
签名(a,b)的产生和验证
5
调试过程中的问题
此程序仅仅局限于int型,int对于文件还有安全性较差。超过int就会出现错误
这就出现错误了。
我们可以进行扩充。把int的数用一个数组来表示。大家都扩到128位。密码也按照一定方法扩到128位。对于m则可以使用hash值。这样可以可以对几乎所有的文件进行签名了。
对于g,此处我使用的随机数g,这会使得签名容易破译。g应该为p的生成元在,然后再生成元中随机取一个。
若一个群G的每一个元都是G的某一个固定元a的乘方,我们就把G叫做循环群;我们也说,G是由元a生成的,并且用符号G=(a)来表示。a叫做G的一个生成元。
关于生成元g产生的方法
int
getGenerator(int
p)
{
int
gTable[LEN];
int
len=0;
int
q=p;
for(int
i=2;i=40)
break;
}
cout
#include
using
namespace
std;
typedef
long
llong;
llong
b[1000],w[1000];
int
mod_exp(int
a,int
b,int
n)
{
int
tmp=a%n,ans=1;
for(;b>0;b>>=1)
{
if(bans%=n;}
tmp*=tmp;tmp%=n;
}
return
ans;
}
int
extended_euclid(int
a,int
b,int
if(b
==
0)
{x
=
1;
y
=
0;
return
a;}
d
=
extended_euclid(b,a
%
b,y,x);
y
-=
a
/
b
x;
return
d;
}
int
chinese_remainder(int
len)
{
int
i,d,x,y,m,n,ret;
ret
=
0;
n
=
1;
for(i=0;
i
>p>>q>>M;
N
=
p*q;
int
C
=
(M*M)%N;
cout1)是素数,如果p的因子只有±1,±p。
称c是两个整数a、b的最大公因子,如果
①
c是a的因子也是b
的因子,即c是a、b的公因子。
②
a和b的任一公因子,也是c的因子。
表示为c=gcd(a,b)。
由于要求最大公因子为正,所以gcd(a,b)=gcd(a,-b)=gcd(-a,b)=gcd(-a,-b)。一般gcd(a,b)=gcd(|a|,|b|)。由任一非0整数能整除0,可得gcd(a,0)=|a|。如果将a,b都表示为素数的乘积,则gcd(a,b)极易确定。
一般由c=gcd(a,b)可得:
对每一素数p,cp=min(ap,bp)。
由于确定大数的素因子不很容易,所以这种方法不能直接用于求两个大数的最大公因子,如何求两个大数的最大公因子在下面介绍。
如果gcd(a,b)=1,则称a和b互素。
2.1.2
模运算
设n是一正整数,a是整数,如果用n除a,得商为q,余数为r,则
a=qn+r,0≤r
n的开方
)
返回n为宿舍;
}
求最大公因子的算法:Euclid算法就是用这种方法,因gcd(a,b)=gcd(|a|,|b|),因此可假定算法的输入是两个正整数,设为d,f,并设f
>d。
Euclid(f,d)
①X←f;
Y←d;
②
if
Y=0
then
return
X=gcd(f,d);
③
R=X
mod
Y;
④
X=Y;
⑤
Y=R;
⑥
goto
②。
求乘法逆元:推广的Euclid算法先求出gcd(a,b),当gcd(a,b)=1时,则返回b的逆元。
Extended
Euclid(f,d)
(设
f
>d)
①
(X1,X2,X3)←(1,0,f);(Y1,Y2,Y3)←(0,1,d);
②
if
Y3=0
then
return
X3=gcd(f,d);no
inverse;
③
if
Y3=1
then
return
Y3=gcd(f,d);Y2=d-1
mod
f;
④
Q=X3Y3
;
⑤
(T1,T2,T3)←(X1-QY1,X2-QY2,X3-QY3);
⑥
(X1,X2,X3)←(Y1,Y2,Y3);
⑦
(Y1,Y2,Y3)←(T1,T2,T3);
⑧
goto
②。
处理明文:将明文的每个字符提取出来将其装换为数字。进行加密处理,将处理后的数字字符用“+”号相连。其中加密的算法为:求am可如下进行,其中a,m是正整数:
将m表示为二进制形式bk
bk-1…b0,即
m=bk2k+bk-12k-1+…+b12+b0
因此:
例如:19=1×24+0×23+0×22+1×21+1×20,所以
a19=((((a1)2a0)2a0)2a1)2a1
从而可得以下快速指数算法:
c=0;
d=1;
For
i=k
downto
0
d0
{
c=2×c;
d=(d×d)
mod
n;
if
bi=1
then
{
c=c+1;
d=(d×a)
mod
n}
}
return
d.
其中d是中间结果,d的终值即为所求结果。c在这里的作用是表示指数的部分结果,其终值即为指数m,c对计算结果无任何贡献,算法中完全可将之去掉。
解密过程:将“+”连接的数字字符转换为数字并相加,用密钥做与
篇2:20XX秋数学实验实验报告4密码学初步
2011秋数学实验实验报告4密码学初步 本文关键词:实验,密码学,数学,报告
2011秋数学实验实验报告4密码学初步 本文简介:年级、专业姓名学号名单序号实验时间MATLAB版本:PC注:实验报告的最后一部分是实验小结与收获实验报告(4):密码学初步1.编一个函数统计一段英文文章中各字母出现的频率。返回值是一个元胞数组,第二个值是文章中按A到Z的顺序各个字母出现的频率。functiony=myStat(filename)ch
2011秋数学实验实验报告4密码学初步 本文内容:
年级、专业
姓名
学号名单序号
实验时间
MATLAB版本:
PC
注:实验报告的最后一部分是实验小结与收获
实验报告(4):密码学初步
1.
编一个函数统计一段英文文章中各字母出现的频率。
返回值是一个元胞数组,第二个值是文章中按A到Z的顺序各个字母出现的频率。
function
y
=
myStat(filename)
ch
=
textread(filename,%c
);
y={};
total
=
0;
y{1}
=
char(65:90);
freq
=
zeros(1,26);
n
=
numel(ch);
for
i
=
1:n
for
j
=
0:25
if
(ch(i)
==
j
+
65
||
ch(i)
==
j
+
97)
freq(j+1)
=
freq(j+1)
+
1;
total
=
total
+
1;
end
end
end
y{2}=
freq/total;
2.
编一个函数,在已知密钥的情况下,用加法密码进行加密和解密。
加密算法:
function
y
=
encrypt(origin,key)
n
=
numel(origin);
for
i
=
1:n
if
(origin(i)
>=
A
else
error(
输入的密钥有误!
)
end
2011秋
数学实验
实验报告(4)密码学初步
3
/
3