1、RSA加密的简易实现要点 安全学实验报告RSA加密解密的简单实现 华南师范大学 赵教授RSA介绍:当前最著名、应用最广泛的公钥系统RSA是在1978年,由美国麻省理工学院(MIT)的Rivest、Shamir和Adleman在题为获得数字签名和公开钥密码系统的方法的论文中提出的。RSA算法是第一个既能用于数据加密也能用于数字签名的算法,因此它为公用网络上信息的加密和鉴别提供了一种基本的方法。它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册,人们用公钥加密文件发送给个人,个人就可以用私钥解密接受。为提高保密强度,RSA密钥至少
2、为500位长,一般推荐使用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(互质),(1e(n))计算d,使d=e -1(mod(n)(求乘法逆元)公钥Pk=e,n;私钥Sk=d,n。 (定义若ax mod n =1,则称a与x对于模n互为逆元) 2.加密 (用e,n) 明文 Mn 由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判断是否与(n)互质,计
4、算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=d )?f:d;y3 = ( f=d )?d:f;while( 1 ) if (
5、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 = 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
6、B分解为较小几个数的乘积分别进行模运算例如(3 999)可以分解为(3 512) * (3 256) * (3 128) * (3 64) * (3 32) * (3 4) * (3 2) * 3 这样只要做16次乘法。把999转为2进制数:1111100111,其各位就是要乘的数。所以程序中要有函数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) digit
7、i+ = 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.总操作界面:1. 输入两个素数P,Q 2. 输入公钥E 3. 查看当前密钥信息 4. 加密 5. 解密 6. 帮助 0. 退出三程序实现流程图:(1)流程图: (2)各功能模块:命令对应函数功能描述1input_P_Q输入素数P,Q2input_E输入公钥E3print_miyao显示密钥信息4jiami加密5jiemi解密6print_help帮助四
8、.程序测试: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位大数进行存取,及简单运算。一个最容易理解的方法就是将大数用十进制表示
9、,并将每一位(0 9)都做为一个单独的数用数组进行管理。做加减乘除等运算时,人工的对其进行进、借位。然而计算机对于10进制数的处理并不在行,而且表示非2n进制的数会浪费很多空间,所以应该采用8进制、16进制、32进制、64进制的表示法,使得每一位数字都能占据一个完整的内存空间。目前绝大多数PC机都是基于32位运算的,所以采用2 32进制表示大数将会很大提高计算机的处理效率。现实中,就使用32位的整数数组进行存储每一位数,另设一个布尔值表示正负。进行计算时常会遇到进位借位的情况,而且常常会超过2 32次方,幸好目前的编译器都支持64位整数,可以满足( 232 - 1 ) * ( 232 - 1
10、)以内的运算,所以使用64位整数作为运算中间量将会是很好的选择。 大数除了加减乘除等基本运算以外,还有一些如赋值、比较、左右移位、或、与等,为了方便使用,我们可以利用面向对象的方法把大数进行封装,并利用C+的特性进行运算符重载,使它成为一个整体对象来进行操作。这样我们就可像使用int一样来使用它了。2.大素数随机生成,以及判断: 真正的RSA加密时密钥的生成应该是自动完成的,而不是用户手动制定p,q,e。所以在使用大数类库后随之而来一个问题就是如何随机的生成两个大素数,以及大素数的判断。由于素数有无穷多个,且没有固定的生成方式,所以大素数的生成基本是采用在一定范围内(比如奇数,且不会被小素数整
11、除的)随机选取大数后再进行素数检测,直到有通过检测的数。 因此大数的素数检测算法就是关键了,如果按照之前的素数检测算法需要依次除2到n的数,时间复杂度O(n)太大。所以我们要用更为快速的算法。米勒拉宾测试是一个不确定的算法,只能从概率意义上判定一个数可能是素数。是目前公认的最高效的素性测试之一。大体步骤如下:输入奇数n,判断n为素数或者合数。计算r和R,使得,R奇。随即选择a,。for i=0 to r,计算。若,则输入合数。若,则输入素数。设j=maxi: ,则输入素数。若,则输出素数,否则输出合数。参考书目:1 刘嘉勇等 应用密码学2 胡道元 闵京华网络安全3张四兰等 可信赖的高效素数生成
12、和检验算法附 程序代码:#include#include #includevoid 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);void 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模拟=
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1