版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 安全学实验报告RSA加密解密的简单实现 华南师范大学 赵教授RSA介绍:当前最著名、应用最广泛的公钥系统RSA是在1978年,由美国麻省理工学院(MIT)的Rivest、Shamir和Adleman在题为获得数字签名和公开钥密码系统的方法的论文中提出的。RSA算法是第一个既能用于数据加密也能用于数字签名的算法,因此它为公用网络上信息的加密和鉴别提供了一种基本的方法。它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册,人们用公钥加密文件发送给个人,个人就可以用私钥解密接受。为提高保密强度,RSA密钥至少为500位长,一般推荐使
2、用1024位。 公钥加密算法中使用最广的是RSA。RSA算法研制的最初理念与目标是努力使互联网安全可靠,旨在解决DES算法秘密密钥的利用公开信道传输分发的难题。而实际结果不但很好地解决了这个难题;还可利用RSA来完成对电文的数字签名以抗对电文的否认与抵赖;同时还可以利用数字签名较容易地发现攻击者对电文的非法篡改,以保护数据信息的完整性。此外,RSA加密系统还可应用于智能IC卡和网络安全产品。 一系统总体方案:1.要求:编写RSA加密解密演示程序,用户自己输入两个素数P,Q以及公钥E,程序判断P,Q为素数后计算得到公钥(e,n),私钥(d,n)并显示。 输入明文密文并可以进
3、行加密解密。2.数学原理: 1.密钥的生成 选择p,q为两个大的互异素数 计算n=p*q, (n)=(p-1)(q-1)选择整数e使gcd(n),e)=1(互质),(1<e<(n))计算d,使d=e -1(mod(n)(求乘法逆元)公钥Pk=e,n;私钥Sk=d,n。 (定义若ax mod n =1,则称a与x对于模n互为逆元) 2.加密 (用e,n) 明文 M<n 由C=M e(mod n)得到密文C。 3.解密 (用d,n) 对于密文C 由M=C d(mod n)得到明文M。 3.实现过程: 1.输入p,q判断为素数,计算n=p*q,(n)=(p-1)(q-1) 2输入e
4、判断是否与(n)互质,计算d= e -1(mod(n) 3.输出公钥为(e,n)私钥为(d,n) 4.输入明文(数字)M计算密文C=M e(mod n) 5.输入密文C计算明文M=C d(mod n)二.设计思路: 1.关键问题: (1)素数的判断:首先在输入p,q之后应该有一个函数int sushu()可以判断p,q是否为素数,并返回 1(是)或0(否)。考虑到程序中数据类型为long型,依次用2n之间的数去除n,如果能整除则不为素数。该算法时间复杂度为O(n)。int sushu(long m)int i; for(i=2;i*i<=m;i+) if(m%i=0)return 0;
5、return 1; (2)互质的判断:在输入e之后需要判断e与(n)是否互质,所以用该有判断互质的函数int gcd()返回1(是),其他(否)。根据欧几里德算法gcd(a,b)=gcd(b,a mod b) 证明:a可以表示成a = kb + r,则r = a mod b 假设d是a,b的一个公约数,则有 d|a, d|b,而r = a - kb,因此d|r 因此d是(b,a mod b)的公约数 假设d 是(b,a mod b)的公约数,则 d | b , d |r ,但是a = kb + r 因此d也是(a,b)的公约数 因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约
6、数也必然相等所以若gcd(a,b)=1 则a与b互质。int gcd(long a, long b)if(b = 0)return a;return gcd(b, a % b); (3)求乘法逆元:因为需要计算私钥d= e -1(mod(n),所以有函数long ExtendedEuclid()计算d并返回d的值,这里用到扩展欧几里德算法。大体思路与欧几里德算法一致:如果gcd(a,b)=d,则存在m,n,使得d = ma + nb,称呼这种关系为a、b组合整数d,m,n称为组合系数。当d=1时,有 ma + nb = 1 ,此时可以看出m是a模b的乘法逆元,n是b模a的乘法逆元。long E
7、xtendedEuclid(long f,long d ,long *result) int x1,x2,x3,y1,y2,y3,t1,t2,t3,q;x1 = y2 = 1;x2 = y1 = 0;x3 = ( f>=d )?f:d;y3 = ( f>=d )?d:f;while( 1 ) if ( y3 = 0 ) *result = x3; return 0; if ( y3 = 1 ) *result = y2; return 1; q = x3/y3; t1 = x1 - q*y1; t2 = x2 - q*y2; t3 = x3 - q*y3; x1 = y1; x2
8、= y2; x3 = y3; y1 = t1; y2 = t2; y3 = t3;(4)快速幂模算法:在加密解密时都要用到类似A B(mod C)的计算,当指数B较大时,如果先计算A B的值时间较慢,且结果过大会溢出。依据模运算的性质(a*b)mod n=(a mod n)*(b mod n)mod n 可以将A B分解为较小几个数的乘积分别进行模运算例如(3 999)可以分解为(3 512) * (3 256) * (3 128) * (3 64) * (3 32) * (3 4) * (3 2) * 3 这样只要做16次乘法。把999转为2进制数:1111100111,其各位就
9、是要乘的数。所以程序中要有函数int a_b_Mod_c(long a, long b, long c)计算a b mod c的值并返回结果。int a_b_Mod_c(long a, long b, long c) int digit32;long i,k,resualt = 1; i = 0; while(b) digiti+ = b%2; b >>= 1; for(k = i-1; k >= 0; k-) resualt=(resualt*resualt)%c; if(digitk=1) resualt=(resualt*a)%c; return resualt;2.总
10、操作界面:1. 输入两个素数P,Q 2. 输入公钥E 3. 查看当前密钥信息 4. 加密 5. 解密 6. 帮助 0. 退出三程序实现流程图:(1)流程图: 输入两个素数p,q计算n=p*q (n)=(p-1)*(q-1)输入一个大于2小于(n)的数e计算d= e -1(mod(n)得到公钥(e,n)私钥(d,n)加密或者解密根据输入的明文M计算密文C= M e(mod n)根据输入的密文C计算明文M= C d(mod n)(2)各功能模块:命令对应函数功能描述1input_P_Q输入素数P,Q2input_E输入公钥E3print_miyao显示密钥信息4jiami加密5jiemi解密6pr
11、int_help帮助四.程序测试:1输入两个素数p=47,q=71 则n=47*71=33372.输入e=79,计算得d=e-1 mod (p-1)(q-1)=79-1 mod 3220=1019 因此公钥为(79,3337)私钥为(1019,3337)3.输入明文 688 并加密4.输入密文1570 并解密五.总结、改进思考:1.大数类库的建立:本程序作为RSA加密解密过程演示程序,变量均为long型,因此密钥长度较小,而RSA的安全性建立在密钥长度很长,大素数难以分解的前提上。所以为了能够提高安全性,应该建立一个大数类库,对512位或1024位大数进行存取,及简单运算。一个最容易理解的方法
12、就是将大数用十进制表示,并将每一位(0 9)都做为一个单独的数用数组进行管理。做加减乘除等运算时,人工的对其进行进、借位。然而计算机对于10进制数的处理并不在行,而且表示非2n进制的数会浪费很多空间,所以应该采用8进制、16进制、32进制、64进制的表示法,使得每一位数字都能占据一个完整的内存空间。目前绝大多数PC机都是基于32位运算的,所以采用2 32进制表示大数将会很大提高计算机的处理效率。现实中,就使用32位的整数数组进行存储每一位数,另设一个布尔值表示正负。进行计算时常会遇到进位借位的情况,而且常常会超过2 32次方,幸好目前的编译器都支持64位整数,可以满足( 232 - 1 ) *
13、 ( 232 - 1 )以内的运算,所以使用64位整数作为运算中间量将会是很好的选择。 大数除了加减乘除等基本运算以外,还有一些如赋值、比较、左右移位、或、与等,为了方便使用,我们可以利用面向对象的方法把大数进行封装,并利用C+的特性进行运算符重载,使它成为一个整体对象来进行操作。这样我们就可像使用int一样来使用它了。2.大素数随机生成,以及判断: 真正的RSA加密时密钥的生成应该是自动完成的,而不是用户手动制定p,q,e。所以在使用大数类库后随之而来一个问题就是如何随机的生成两个大素数,以及大素数的判断。由于素数有无穷多个,且没有固定的生成方式,所以大素数的生成基本是采用在一定范围内(比如
14、奇数,且不会被小素数整除的)随机选取大数后再进行素数检测,直到有通过检测的数。 因此大数的素数检测算法就是关键了,如果按照之前的素数检测算法需要依次除2到n的数,时间复杂度O(n)太大。所以我们要用更为快速的算法。米勒拉宾测试是一个不确定的算法,只能从概率意义上判定一个数可能是素数。是目前公认的最高效的素性测试之一。大体步骤如下:输入奇数n,判断n为素数或者合数。计算r和R,使得,R奇。随即选择a,。for i=0 to r,计算。若,则输入合数。若,则输入素数。设j=maxi:,则输入素数。若,则输出素数,否则输出合数。参考书目:1 刘嘉勇等 应用密码学2 胡道元 闵京华网络安全3张四兰等
15、可信赖的高效素数生成和检验算法附 程序代码:#include<iostream.h>#include <stdlib.h>#include<stdio.h>void input_P_Q(long &P,long &Q,long &N,long &N1);void input_E(long &E,long &D,long n1);void print_miyao(long e,long n,long d);void jiami(long e,long n);void jiemi(long d,long n);vo
16、id print_help();int sushu(long m);int gcd(long a, long b);long ExtendedEuclid(long f,long d ,long *result);int a_b_Mod_c(long a, long b, long c);void main()long P=0,Q=0,E=0,N=0,N1=0,D=0;cout<<"=RSA模拟="<<endl; cout<<" 1. 输入两个素数P,Qn"cout<<" 2. 输入公钥En&qu
17、ot;cout<<" 3. 查看当前密钥信息n"cout<<" 4. 加密n"cout<<" 5. 解密n"cout<<" 6. 帮助n"cout<<" 0. 退出n"cout<<"n 输入你的选择:"long ch;do cin>>ch; switch(ch) case 1 : input_P_Q(P,Q,N,N1);break; case 2 : input_E(E,D,N1);break
18、; case 3 : print_miyao(E,N,D);break; case 4 : jiami(E,N);break; case 5 : jiemi(D,N);break; case 6 : print_help();break; case 0 : break;while(ch);int gcd(long a, long b)if(b = 0)return a;return gcd(b, a % b);int sushu(long m) int i; for(i=2;i*i<=m;i+) if(m%i=0) return 0; return 1;long ExtendedEucl
19、id(long f,long d ,long *result)int x1,x2,x3,y1,y2,y3,t1,t2,t3,q;x1 = y2 = 1;x2 = y1 = 0;x3 = ( f>=d )?f:d;y3 = ( f>=d )?d:f;while( 1 ) if ( y3 = 0 ) *result = x3; return 0; if ( y3 = 1 ) *result = y2; return 1; q = x3/y3; t1 = x1 - q*y1; t2 = x2 - q*y2; t3 = x3 - q*y3; x1 = y1; x2 = y2; x3 = y
20、3; y1 = t1; y2 = t2; y3 = t3;int a_b_Mod_c(long a, long b, long c) int digit32;long i,k,resualt = 1; i = 0; while(b) digiti+ = b%2; b >>= 1; for(k = i-1; k >= 0; k-) resualt=(resualt*resualt)%c; if(digitk=1) resualt=(resualt*a)%c; return resualt;void input_P_Q(long &P,long &Q,long &
21、amp;N,long &N1) cout<<"输入第一个素数p:n"while(1) if (cin>>P) break; else cout<<"P应为数字,请重新输入:"<<endl; cin.clear(); cin.ignore(); while(1) if (sushu(P) break; else cout<<"P应为素数,请重新输入:"<<endl; cin.clear(); cin.ignore(); cin>>P;cout&l
22、t;<"输入第二个素数Q:n"while(1) if (cin>>Q) break; else cout<<"Q应为数字,请重新输入:"<<endl; cin.clear(); cin.ignore(); while(1) if (sushu(Q) break; else cout<<"Q应为素数,请重新输入:"<<endl; cin.clear(); cin.ignore(); cin>>Q;N=P*Q;N1=(P-1)*(Q-1);void input_
23、E(long &E,long &D,long n1)if(n1=0)cout<<"请先输入两个素数P,Q"<<endl;return;long z=0;cout<<"输入一个小于"<<n1<<"的数e:n"while(1) if (cin>>E) break; else cout<<"E应为数字,请重新输入:"<<endl; cin.clear(); cin.ignore(); while(1) if (
24、gcd(E,n1)=1) break; else cout<<"E应与"<<n1<<"互质"<<",请重新输入:"<<endl; cin.clear(); cin.ignore(); cin>>E;if(ExtendedEuclid(E,n1,&z) D=z; else cout<<"错误"<<endl;void print_miyao(long e,long n,long d)cout<<"
25、;公钥为:n" cout<<"("<<e<<","<<n<<")"<<endl;cout<<"公钥为:n" cout<<"("<<d<<","<<n<<")"<<endl;void jiami(long e,long n)if(e=0,n=0)cout<<"请先输入密钥"<<endl;return;long c,m;cout<<"输入要加密的明文:n"while(1) if (cin>>m) break; else cout<
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 房地产抵押协议书
- 人工机械合同协议书
- 装修工程补充合同年
- 2025年玉树货运资格证考题
- 2025年扬州下载货运从业资格证模拟考试题
- 2025年山西货运资格考试答案
- 电商和快递合作合同(2篇)
- 西北师范大学图书馆
- 社区服务活动总结
- 总经理办公室工作计划
- 综采工作面过空巷安全技术措施
- 云南省丽江市2025届高三上学期复习统一检测试题 物理 含解析
- 建材材料合作合同范例
- 2025年集体经济发展计划
- 病历书写规范细则(2024年版)
- 2024-2025学年人教版八年级上册地理期末测试卷(二)(含答案)
- 做账实操-牙科诊所的账务处理
- 双方共同买车合同范例
- 汽车智能制造技术课件
- 中医外治法课件
- 2025届山东省滨州市三校联考语文高三第一学期期末质量跟踪监视试题含解析
评论
0/150
提交评论