1、密码学实验4实验4 非对称密码算法RSA一、 实验目的通过实际编程了解非对称密码算法RSA的加密和解密过程,加深对非对称密码算法的认识。二、 实验原理1、算法原理步骤如下(这里设B为是实现者)(1)B寻找出两个大素数p和q。(2)B计算出n=p*q和(n)=)(p-1)*(q-1)。(3)B选择一个随机数e(0e (n)),满足(e, (n)=1 (即e与欧拉函数互素(n))。(4)B使用欧几里得算法计算e的模余(n)的乘法逆元素d。(5)B在目录中公开n和e作为他的公开密钥,保密p、q和d。加密时,对每一明文m计算密文 cme(modn)解密时,对每一密文c计算明文 mcd(modn)三、
2、实验环境运行Windows或者Linux操作系统的PC机,具有gcc(Linux)、VC(Windows)等C语言编译环境。四、 实验内容1、为了加深对算法的了解,根据输入的参数p,q,M,手工计算公私钥,并对明文进行加密,然后对密文进行解密。2、编写程序,加密一段文字,了解算法原理。尝试加密一大段文字,记录程序的运行时间。使用DES算法加密相同的文字,比较两种算法加密的速度。3、编写一个程序,随机选择3个 较大的数,计算,记录 程序运行时间。查阅资料给出简单说明大数在计算机上是如何表示,如何进行运算。4、查阅资料,找出目前实际可行的素数判定法则,并比较各自的优缺点。五、实验步骤1、主要函数说
3、明(1)判断一个数是否为素数函数bool prime(int n) int m=sqrt(n); for(int i=2;i=m) return 1; else return 0;(2)模幂算法 (这里以明文m为一个为例)令f=1;用for循环遍历从i=1到i=b,令f=(f*a)%n输出f,f的值即为模幂的结果。int multiplication(int a,int b,int n) int f=1; for(int i=1;i=d) x3=f; y3=d; else x3=d; y3=f; while( 1 ) if ( y3 = 1 ) *result = y2; /* 两个数互素则r
4、esutl为其乘法逆元,此时返回值为1 */ 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)主函数输入两个数字判断是否为素数,当不为素数时重新输入。如输入 17 11输入e,得到公钥。如输入e为7调用ExtendedEuclid(e,N,&d)函数,得到d,和私钥。如d=23输入明文长度。如输入 5 如输入明文为 56 88 78 12 23开始加密,调用加密函数 Encryption()。
5、 则输入密文为 78 11 56 177 133开始解密,调用解密函数 Decipher()。 则解密后明文为 56 88 78 12 232、打开VC+,编写程序如下:#include#includeint p,q,n,e,d,N,m1100,m2100,len; /判断一个数是否为素数,为素数返回1,否则返回0bool prime(int n) int m=sqrt(n); for(int i=2;i=m) return 1; else return 0;/扩展欧几里得算法求乘法逆元,两数互素返回1int ExtendedEuclid( int f,int d ,int *result)
6、int x1,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 */ 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; /将十进制数据转
7、化为二进制数组void to_bit(int b,int bit32) int n=0; while(b0) bitn=b%2; n+; b/=2; /模幂算法int multiplication(int a,int b,int n) int f=1;for(int i=1;i=b;i+) f=(f*a)%n; return f;/加密函数void Encryption() cout*开始加密*endl; int i; cout请输入明文:; for(i=0;im1i; for(i=0;ilen;i+) m2i=multiplication(m1i,e,n); cout加密后的密文为:; fo
8、r(i=0;ilen;i+) coutm2i ; coutendl;/解密函数void Decipher() int i; cout*开始解密*endl; for(i=0;ilen;i+) m2i=multiplication(m2i,d,n); cout解密后的明文为:; for(i=0;ilen;i+) coutm2i ; coutendl;void main() coutp; if(prime(p) coutp是素数endl; break; else coutp不是素数q; if(prime(q) coutq是素数endl; break; else coutq不是素数endl; cont
9、inue; cout两个素数为:p,qendl; n=p*q; N=(p-1)*(q-1); for(int i=2;iN;i+) if(N%i=0) couti ; coutendl; cout请输入一个随机数,该数不等于上面的任何一个数!e; cout公钥为e,nendl; if(ExtendedEuclid(e,N,&d) coute的乘法逆元是:dendl; cout私钥为d,nendl; coutlen; Encryption(); Decipher();调试程序,程序运行如下:3、打开VC+,编写程序如下:(此程序错误,因为数值过大产生溢出,请改之)#include#include
10、 #include#include#include#include#include /using namespace std;int main() clock_t start,end; long times; long x,e,n; cout随机产生3个大数:endl; /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、)%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; coutx=x e=e n=nendl; start=clock(); coutpow(x
12、,e)endl; long answer=(int)pow(x,e)%n; /指数运算 end=clock(); times=1000*(end-start); cout花费的时间为:timesendl; return 0;调试运行如下:计算机上大数表示方法:将大数看作一个n进制数组,对于目前的32位系统而言,n可以取值为2的32次方,即0x10000000,假如将一个1024位的大数转化成0x10000000进制,它就变成了32位,而每一位的取值范围就不是0-1或0-9,而是0-0xfffffff.我们正好可以用一个无符号长整数来表示这一数值.所以1024位的大整数就是一个有32个元素的un
13、signed long数组.而且0x10000000进制的数组排列与2进制流对于计算机来说,实际上是一回事,但是我们完全可以针对unsighed long数组进行”竖式计算”,而循环规模被降低到了32次之内,并且算法很容易理解.4、素性测试方法:所谓素数,是指除了能被1和它本身整除而不能被其他任何数整除的数。据此,只需用2到N-1去除N,如果都除不尽,则为素数 (1)flag=1,i=2(2)If n mod i=0 then flag=1 else i=i+1(3)If flag=0 and in-1 then(2) else (4)(4)If flag=0 then write yes e
14、lse no在最坏的情况下,即N为素数,算法需要执行N-2次,时间复杂性太大。只需用2到根下N去除N,即可,于是上述算法改为(3)If flag=0 and i=int(根N) then(2) else (4)虽然快了不小,但有重复计算,如果用2去除N时若不尽,则用2的倍数去除N也除不尽,由此得(1)for(i=2;int(根N);i+) marki=0;/mark是标记其初值为0,只要它的因子除不尽其值变为1(2)i=2,flag=0(3)while(flag=0 and iint(根N) If marki=0Then If n mod i=0Then flag=1S=i+iWhile sint(根N) Marks=1S=s+i I=i+1(4)if flag=0 then yes else no
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1