实验项目2 :RSA算法

实验二  RSA数字签名

一、实验目的

(1)了解RSA算法的特点

(2)掌握RSA算法的加解密原理

(3)掌握RSA数字签名算法的原理

二、实验内容

   RSA 公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。

RSA 算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。

RSA 的算法涉及三个参数,n、e1、e2。其中,n是两个大质数 p、 q 的积, n 的二进制表示时所占用的位数,就是所谓的密钥长度。e1 和 e2 是一对相关的值, e1 可以任意取,但要求 e1 与 (p-1)*(q-1 )互质; 再选择 e2,要求( e2*e1 )mod((p-1 )*(q-1 ))=1 。( n,e1),(n,e2)就是密钥对。其中 (n, e1)为公钥, (n, e2)为私钥。

RSA 加解密的算法完全相同, 设 A 为明文, B 为密文,则: A=B^e2 mod n ;B=A^e1 mod n ;(公钥加密体制中,一般用公钥加密,私钥解密)e1 和 e2 可以互换使用,即:A=B^e1 mod n ; B=A^e2 mod n;

密钥生成:

首先要使用概率算法来验证随机产生的大的整数是否质数,这样的算法比较快而且可以消除掉大多数非质数。假如有一个数通过了这个测试的话,那么要使用一个精确的测试来保证它的确是一个质数。

密钥分配:

和其它加密过程一样,对RSA 来说分配公钥的过程是非常重要的。分配公钥的过程必须能够抵挡一个从中取代的攻击。假设 Eve 交给  Bob 一个公钥,并使Bob 相信这是  Alice 的公钥,并且她可以截下Alice 和 Bob 之间的信息传递,那么她可以将她自己的公钥传给   Bob,Bob 以为这是  Alice 的公钥。

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

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

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

( 3)B 选择一个随机数e( 0<e< (n) ) ,满足( e, (n))=1 (即 e 与欧拉函数互素(n))。

( 4)B 使用欧几里得算法计算e 的模余(n)的乘法逆元素d。

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

 

开始

输入两个素数pq

 

输入不等于N公约数的e

 

调用ExtendEuclid(e,N,&d)

 

找出N=p-1*(q-1)的所有公约数

 

开始加密调用Encryption()

 

调用Prime()

 

Yes

 

No

 

输出明文,结束

i=0

 

i++

 

输入明文长度Len及明文

 

调用multiplication(m1[i],e,n)

 

i<len

Yes

 

i=0

 

No

 

输出密文

 

开始解密调用Decipher()

 

i<len

调用multiplication(m1[i],e,n)

 

i++

 

Yes

 

No

 

加密时,对每一明文m 计算密文cΞme ( modn )

 

解密时,对每一密文c 计算明文mΞcd ( modn )

算法流程图如下所示:

 

 

 

 

 

 

 

 

 

                          

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

三、实验结果:

 

四、实验源代码:

#include<iostream.h>

#include<math.h>

#include<stdio.h>

typedef int Elemtype;

Elemtype p,q,e;

Elemtype fn;

Elemtype m,c;

int flag=0;

typedef void(*Msghandler)(void);

struct MsgMap{

char ch;

Msghandler handler;

};

/* 公钥*/

struct PU{

Elemtype e;

Elemtype n;

}pu;

/* 私钥*/

struct PR{

Elemtype d;

Elemtype n;

}pr;

/* 判定一个数是否为素数*/

bool test_prime(Elemtype m){

if(m<=1){

return false;

}

else if(m==2){

return true;

}

else{

for(int i=2;i<=sqrt(m);i++){

if((m%i)==0){

return false;

break;

}

}

return true;

}

}

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

void switch_to_bit(Elemtype b,Elemtype bin[32]){

int n=0;

while(b>0){

bin[n]=b%2;

n++;

b/=2;

}

}

/* 初始化主界面*/

void Init(){

cout<<"******************************************"<<endl;

cout<<"*** Welcome to use RSA encoder ***"<<endl;

cout<<"*** 1.setkey ***"<<endl;

cout<<"*** 2.加密***"<<endl;

cout<<"*** 3.解密***"<<endl;

cout<<"*** 4.退出***"<<endl;

cout<<"******************************************"<<endl;

cout<<"press a key:"<<endl;

}

/* 将两个数排序,大的在前面*/

void order(Elemtype &in1,Elemtype &in2){

Elemtype a=(in1>in2?in1:in2);

Elemtype b=(in1<in2?in1:in2);

in1=a;

in2=b;

}

/* 求最大公约数*/

Elemtype gcd(Elemtype a,Elemtype b){

order(a,b);

int r;

if(b==0){

return a;

}

else{

while(true){

r=a%b;

a=b;

b=r;

if(b==0){

return a;

break;

}

}

}

}

/* 用扩展的欧几里得算法求乘法逆元*/

Elemtype extend_euclid(Elemtype m,Elemtype bin){

order(m,bin);

Elemtype a[3],b[3],t[3];

a[0]=1,a[1]=0,a[2]=m;

b[0]=0,b[1]=1,b[2]=bin;

if(b[2]==0){

return a[2]=gcd(m,bin);

}

if(b[2]==1){

return b[2]=gcd(m,bin);

}

while(true){

if(b[2]==1){

return b[1];

break;

}

int q=a[2]/b[2];

for(int i=0;i<3;i++){

t[i]=a[i]-q*b[i];

a[i]=b[i];

b[i]=t[i];

}

}

}

/* 快速模幂算法*/

Elemtype modular_multiplication(Elemtype a,Elemtype b,Elemtype n){

Elemtype f=1;

Elemtype bin[32];

switch_to_bit(b,bin);

for(int i=31;i>=0;i--){

f=(f*f)%n;

if(bin[i]==1){

f=(f*a)%n;

}

}

return f;

}

/* 产生密钥*/

void produce_key(){

cout<<" 输入素数p 和q:";

cin>>p>>q;

while(!(test_prime(p)&&test_prime(q))){

cout<<" 输入错误,请重新输入!"<<endl;

cout<<" 输入素数p 和q:";

cin>>p>>q;

};

pr.n=p*q;

pu.n=p*q;

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

cout<<"fn 为: "<<fn<<endl;

cout<<" 输入随机数e:";

cin>>e;

while((gcd(fn,e)!=1)){

cout<<"e 输入错误,请重新输入!"<<endl;

cout<<" 输入随机数e:";

cin>>e;

}

pr.d=(extend_euclid(fn,e)+fn)%fn;

pu.e=e;

flag=1;

cout<<" 公钥(e,n) :"<<pu.e<<","<<pu.n<<endl;

cout<<" 私钥d:"<<pr.d<<endl;

cout<<" 请输入下一步操作序号:"<<endl;

}

/* 加密*/

void encrypt(){

if(flag==0){

cout<<"setkey first:"<<endl;

produce_key();

}

cout<<" 输入明文m:";

cin>>m;

c=modular_multiplication(m,pu.e,pu.n);

cout<<" 密文c 为:"<<c<<endl;

cout<<" 请输入下一步操作序号:"<<endl;

}

/* 解密*/

void decrypt(){

if(flag==0){

cout<<"setkey first:"<<endl;

produce_key();

}

cout<<" 输入密文c:";

cin>>c;

m=modular_multiplication(c,pr.d,pr.n);

cout<<" 明文m 为:"<<m<<endl;

cout<<" 请输入下一步操作序号:"<<endl;

}

/* 消息映射*/

MsgMap Messagemap[]={

{'1',produce_key},

{'3',decrypt},

{'2',encrypt},

{'4',NULL}

};

/* 主函数,提供循环*/

void main(){

Init();

char d;

while((d=getchar())!='4'){

int i=0;

while(Messagemap[i].ch){

if(Messagemap[i].ch==d){

Messagemap[i].handler();

break;

}

i++;}

} }

五、实验心得:

通过本次试验学会了RSA算法的基本特点,掌握了RSA算法的加解密原理。

特别要注意的是,RSA 的算法的三个参数,n、e1、e2。其中,n是两个大质数p、 q 的积, n 的二进制表示时所占用的位数,就是所谓的密钥长度。e1 和 e2 是一对相关的值,  e1 可以任意取,但要求 e1 与 (p-1)*(q-1 )互质; 再选择 e2,要求( e2*e1 )mod((p-1 )*(q-1 ))=1 。( n,e1),(n,e2)就是密钥对。其中 (n, e1)为公钥, (n, e2)为私钥。理解互质,公钥与私钥之间的关系非常重要。

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

静水流深深深!

谢谢你的鼓励,我感激不尽!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值