密码学实验4.docx

上传人:b****7 文档编号:9671416 上传时间:2023-02-05 格式:DOCX 页数:15 大小:49.85KB
下载 相关 举报
密码学实验4.docx_第1页
第1页 / 共15页
密码学实验4.docx_第2页
第2页 / 共15页
密码学实验4.docx_第3页
第3页 / 共15页
密码学实验4.docx_第4页
第4页 / 共15页
密码学实验4.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

密码学实验4.docx

《密码学实验4.docx》由会员分享,可在线阅读,更多相关《密码学实验4.docx(15页珍藏版)》请在冰豆网上搜索。

密码学实验4.docx

密码学实验4

实验4非对称密码算法RSA

一、实验目的

通过实际编程了解非对称密码算法RSA的加密和解密过程,加深对非对称密码算法的认识。

二、实验原理

1、算法原理

步骤如下(这里设B为是实现者)

(1)B寻找出两个大素数p和q。

(2)B计算出n=p*q和

(n)=)(p-1)*(q-1)。

(3)B选择一个随机数e(0

(n)),满足(e,

(n))=1(即e与欧拉函数互素

(n))。

(4)B使用欧几里得算法计算e的模余

(n)的乘法逆元素d。

(5)B在目录中公开n和e作为他的公开密钥,保密p、q和d。

加密时,对每一明文m计算密文

cΞme(modn)

解密时,对每一密文c计算明文

mΞcd(modn)

三、实验环境

运行Windows或者Linux操作系统的PC机,具有gcc(Linux)、VC(Windows)等C语言编译环境。

四、实验内容

1、为了加深对

算法的了解,根据输入的参数p,q,M,手工计算公私钥,并对明文进行加密,然后对密文进行解密。

2、编写

程序,加密一段文字,了解

算法原理。

尝试加密一大段文字,记录程序的运行时间。

使用DES算法加密相同的文字,比较两种算法加密的速度。

3、编写一个程序,随机选择3个较大的数

,计算

,记录程序运行时间。

查阅资料给出简单说明大数在计算机上是如何表示,如何进行运算。

4、查阅资料,找出目前实际可行的素数判定法则,并比较各自的优缺点。

五、实验步骤

1、主要函数说明

(1)判断一个数是否为素数函数

boolprime(intn)

{

intm=sqrt(n);

for(inti=2;i

{

if(n%i==0)

break;

}

if(i>=m)

return1;

elsereturn0;

}

 

(2)模幂算法(这里以明文m为一个为例)

①令f=1;

②用for循环遍历从i=1到i=b,令f=(f*a)%n

③输出f,f的值即为模幂的结果。

intmultiplication(inta,intb,intn)

{

intf=1;

for(inti=1;i<=b;i++)

{

f=(f*a)%n;

}

returnf;

}

(3)扩展欧几里得算法

由扩展欧几里得算法可以计算整数s和t,使得s*e+t*N=(e,N)=1,则e的乘法逆元等价于smodN。

①定义变量x1,x2,x3,y1,y2,y3,t1,t2,t3,q;

②令x1=y2=1;x2=y1=0;

③计算q=x3/y3;t1=x1-q*y1;

t2=x2-q*y2;t3=x3-q*y3;

④x1=y1;x2=y2;x3=y3;y1=t1;y2=t2;y3=t3;

⑤当y3=1时,*result=y2;result的结果即为所求乘法逆元;如果y3!

=1,则返回顺序执行③、④步直到满足y3=1

intExtendedEuclid(intf,intd,int*result)

{

intx1,x2,x3,y1,y2,y3,t1,t2,t3,q;

x1=y2=1;

x2=y1=0;

if(f>=d)

{

x3=f;

y3=d;

}

else

{

x3=d;

y3=f;

}

while

(1)

{

if(y3==1)

{

*result=y2;/*两个数互素则resutl为其乘法逆元,此时返回值为1*/

return1;

}

q=x3/y3;

t1=x1-q*y1;

t2=x2-q*y2;

t3=x3-q*y3;

x1=y1;

x2=y2;

x3=y3;

y1=t1;

y2=t2;

y3=t3;

}

}

(4)主函数

①输入两个数字判断是否为素数,当不为素数时重新输入。

如输入1711

②输入e,得到公钥。

如输入e为7

③调用ExtendedEuclid(e,N,&d)函数,得到d,和私钥。

如d=23

④输入明文长度。

如输入5如输入明文为5688781223

⑤开始加密,调用加密函数Encryption()。

则输入密文为781156177133

⑥开始解密,调用解密函数Decipher()。

则解密后明文为5688781223

2、打开VC++,编写程序如下:

#include

#include

intp,q,n,e,d,N,m1[100],m2[100],len;

//判断一个数是否为素数,为素数返回1,否则返回0

boolprime(intn)

{

intm=sqrt(n);

for(inti=2;i

{

if(n%i==0)

break;

}

if(i>=m)

return1;

elsereturn0;

}

//扩展欧几里得算法求乘法逆元,两数互素返回1

intExtendedEuclid(intf,intd,int*result)

{

intx1,x2,x3,y1,y2,y3,t1,t2,t3,q;

x1=y2=1;

x2=y1=0;

if(f>=d)

{

x3=f;

y3=d;

}

else

{

x3=d;

y3=f;

}

while

(1)

{

if(y3==1)

{

*result=y2;/*两个数互素则resutl为其乘法逆元,此时返回值为1*/

return1;

}

q=x3/y3;

t1=x1-q*y1;

t2=x2-q*y2;

t3=x3-q*y3;

x1=y1;

x2=y2;

x3=y3;

y1=t1;

y2=t2;

y3=t3;

}

}

 

//将十进制数据转化为二进制数组

voidto_bit(intb,intbit[32])

{

intn=0;

while(b>0)

{

bit[n]=b%2;

n++;

b/=2;

}

}

//模幂算法

intmultiplication(inta,intb,intn)

{

intf=1;

for(inti=1;i<=b;i++)

{

f=(f*a)%n;

}

returnf;

}

//加密函数

voidEncryption()

{

cout<<"******************开始加密*****************"<

inti;

cout<<"请输入明文:

";

for(i=0;i

cin>>m1[i];

for(i=0;i

m2[i]=multiplication(m1[i],e,n);

cout<<"加密后的密文为:

";

for(i=0;i

cout<

cout<

}

//解密函数

voidDecipher()

{

inti;

cout<<"*************开始解密*************"<

for(i=0;i

m2[i]=multiplication(m2[i],d,n);

cout<<"解密后的明文为:

";

for(i=0;i

cout<

cout<

}

voidmain()

{

cout<<"输入两个素数p和q:

\n";

while

(1)

{

cin>>p;

if(prime(p))

{

cout<

break;

}

else

{

cout<

continue;

}

}

while

(1)

{

cin>>q;

if(prime(q))

{

cout<

break;

}

else

{

cout<

continue;

}

}

cout<<"两个素数为:

"<

n=p*q;

N=(p-1)*(q-1);

for(inti=2;i

{

if(N%i==0)

{

cout<

}

}

cout<

cout<<"请输入一个随机数,该数不等于上面的任何一个数!

"<

cin>>e;

cout<<"公钥为<"<"<

if(ExtendedEuclid(e,N,&d))

cout<

"<

cout<<"私钥为<"<"<

cout<<"请输入明文长度:

";

cin>>len;

Encryption();

Decipher();

}

调试程序,程序运行如下:

3、打开VC++,编写程序如下:

(此程序错误,因为数值过大产生溢出,请改之)

#include

#include

#include

#include

#include

#include

#include

//usingnamespacestd;

intmain(){

clock_tstart,end;

longtimes;

longx,e,n;

cout<<"随机产生3个大数:

"<

//x=1000*(rand()%11)+100*(rand()%11)+10*(rand()%11)+rand()%11;

x=1000000*(rand()%11)+100000*(rand()%11)+10000*(rand()%11)+1000*(rand()%11)+

100*(rand()%11)+10*(rand()%11)+rand()%11;

e=1000000*(rand()%11)+100000*(rand()%11)+10000*(rand()%11)+1000*(rand()%11)+

100*(rand()%11)+10*(rand()%11)+rand()%11;

n=1000000*(rand()%11)+100000*(rand()%11)+10000*(rand()%11)+1000*(rand()%11)+

100*(rand()%11)+10*(rand()%11)+rand()%11;

cout<<"x="<

start=clock();

cout<

longanswer=(int)pow(x,e)%n;//指数运算

end=clock();

times=1000*(end-start);

cout<<"花费的时间为:

"<

return0;

}

调试运行如下:

计算机上大数表示方法:

将大数看作一个n进制数组,对于目前的32位系统而言,n可以取值为2的32次方,即0x10000000,假如将一个1024位的大数转化成0x10000000进制,它就变成了32位,而每一位的取值范围就不是0-1或0-9,而是0-0xfffffff.我们正好可以用一个无符号长整数来表示这一数值.所以1024位的大整数就是一个有32个元素的unsignedlong数组.而且0x10000000进制的数组排列与2进制流对于计算机来说,实际上是一回事,但是我们完全可以针对unsighedlong数组进行”竖式计算”,而循环规模被降低到了32次之内,并且算法很容易理解.

4、素性测试方法:

所谓素数,是指除了能被1和它本身整除而不能被其他任何数整除的数。

据此,只需用2到N-1去除N,如果都除不尽,则为素数

(1)flag=1,i=2

(2)Ifnmodi=0thenflag=1elsei=i+1

(3)Ifflag=0andi

(2)else(4)

(4)Ifflag=0thenwriteyeselseno

在最坏的情况下,即N为素数,算法需要执行N-2次,时间复杂性太大。

只需用2到根下N去除N,即可,于是上述算法改为

(3)Ifflag=0andi<=int(根N)then

(2)else(4)

虽然快了不小,但有重复计算,如果用2去除N时若不尽,则用2的倍数去除N也除不尽,由此得

(1)for(i=2;int(根N);i++)mark[i]=0;//mark是标记其初值为0,只要它的因子除不尽其值变为1

(2)i=2,flag=0

(3)while(flag=0andi

Ifmark[i]=0

Then{

Ifnmodi=0

Thenflag=1

S=i+i

Whiles

Mark[s]=1

S=s+i

}

}

I=i+1

}

(4)ifflag=0thenyeselseno

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1