70 likes | 264 Views
第 4 章 数据加解密 实训 2-1 : RSA 算法设计. 实训目的. 掌握公开密钥体制基本原理 ; 掌握 RSA 算法的原理以及产生公钥和私钥的方法,通过 C++ 编程实现 RSA 算法,加深对 RSA 加密体制的了解,提高逻辑思维能力和编程技术。. 实训要求. 分析 RSA 算法的功能需求,详细设计实现 RSA 算法的数据结构和流程,给出测试用例和测试步骤,得出测试和结论。 程序设计说明 包括变量定义、模块组成、接口说明、使用方法、运行要求等。 实验过程中所碰到问题和解决方法. 实训步骤. 1.RSA 算法描述
E N D
实训目的 掌握公开密钥体制基本原理; 掌握RSA算法的原理以及产生公钥和私钥的方法,通过C++编程实现RSA算法,加深对RSA加密体制的了解,提高逻辑思维能力和编程技术。
实训要求 分析RSA算法的功能需求,详细设计实现RSA算法的数据结构和流程,给出测试用例和测试步骤,得出测试和结论。 程序设计说明 包括变量定义、模块组成、接口说明、使用方法、运行要求等。 实验过程中所碰到问题和解决方法
实训步骤 1.RSA 算法描述 (1)取两个随机大素数p和q(保密) (2)计算公开的模数n = p*q(公开) (3)计算秘密的欧拉函数φ(n)=(p-1)*(q-1)(保密),两个素数p和q不 再需要,应该丢弃,不要让任何人知道。 (4)随机选取整数e,满足1<e<φ(n),gcd(φ(n),e)=1(公开e,加密密钥) (5)在模φ(n)下,计算e的乘法逆元d,满足: e· d ≡ 1 mod φ(n) (保密d,解密密钥) (6)将明文x(其值的范围在0到n-1之间)按模为n自乘e次幂以完成加密 操作,从而产生密文 y(其值也在0到r-1范围内)y=xe (mod n) (7)将密文y按模为n自乘d次幂,完成解密操作 x=yd (mod n)
实验要求与提示 • 从键盘输入两个素数 p,q,并输出参数 N, φ(N), e, d • 从键盘输入明文数据 m,计算出密文数据 c • 从键盘输入密文数据 c,计算出明文数据 m • 如何判断一个数是素数 • 如何判断两个数互素 • 乘法逆元怎么实现 • 当p=7,q=17,e=5,d=77,加密m=19,得出实验结果 • 如果加密的消息为char类型,如何实现加解密?(不强制要求做,但能实现的同学有加分!!)
实验内容 1.分析RSA算法 2.设计RSA算法实现流程图 3.用C++语言或其他语言实现RSA算法 设计产生素数程序模块: void primes() 设计检查是否为素数的模块:int check(int n) 设计求最大公约数模块: int gcd(int a, int b) 设计求乘逆模块 :int pf_c(int m,int k) 设计选择密钥算法:void ckey() 设计加密信息模块:pf_c1() 设计界面信息模块:pf_c2() 设计主程序进行操作菜单选择 4.调试程序
附:用于参考的RSA算法源代码(部分函数自己补充)附:用于参考的RSA算法源代码(部分函数自己补充) #include<iostream.h> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> int r,sk,pk,Euler; primes1(int n1)//判断素数 { ///判断n1是否为素数,是则返回n1, 否则返回0 return 0; return n1; } //欧几里德算法求解最大公约数 int gcd(int a, int b) { //a为初选密钥,b为欧拉函数值 int c,c1,b1; c=b;a=a+1;b1=b; do {a--;c=a;c1=1;b=b1; while(c1!=0)//求解最大公约 { c1=b%c;if (c1!=0){b=c;c=c1;}; } }while(c>1);//最大公约数gcd(a,b)=1 return(a);//返回初选密钥值 } //检查n是否是素数 int check(int n) { int sq1; n=abs(n);sq1=1; do { sq1=primes1(n); if (sq1==0) { cout<<"输入值不是素数,请重新输入"<<endl; cin>>n; } } while(sq1==0); return n;//返回素数 } void primes() {int p,q; cout<<"输入值不要太大,防止溢出"<<endl; cout<<"请输入p:";cin>>p; p=check(p); cout<<"请输入q:";cin>>q; q=check(q); r=p*q; cout<<"素数 "<<"p="<<p<<" q="<<q; Euler=(p-1)*(q-1); cout<<" 欧拉函数:"<<Euler; cout<<" 公开模数:"<<r<<endl<<endl; } int input(int m) {while(m>=r) {cout<<"m 值太大,请再输入编码"; m=abs(m);cin>>m;} return m;//返回编码。 } //使用"平方-乘"算法计算m mod r int pf_c(int m,int k) {int a,i1,a1,b[50]; unsigned long c1; double long c; c=1;c1=1;i1=0; do // 将十进制转换成二进制 { a=(int)ceil(k/2);a1=(k%2); b[i1]=a1;k=a;i1++; }while (a>0); i1--;//"平方-乘"算法 for (int i=i1;i>=0;i--) {c=fmod(c*c,r);if (b[i]==1)c=fmod(c*m,r);} c1=(int)ceil(c); return c1; } //欧几里德扩展算法求解sk*pk≡1mod r void ckey() {int a,c,b1,b2,p,q; cout<<"输入值不要太大,防止溢出"<<endl; cout<<"请输入初选密钥:"; cin>>sk;sk++; do {sk--;sk=abs(sk); b1=1,b2=0; sk=gcd(sk,Euler);a=sk;c=Euler; do{q=(int)ceil(c/a);p=c%a; pk=b2-b1*q;c=a;a=p;b2=b1;b1=pk; }while (p!=1); pk=abs(pk); a=pf_c(9,sk);c=pf_c(a,pk); } while(c!=9);//加密、解密正确判断 cout<<"sk="<<sk<<",pk="<<pk<<endl; } void pf_c1() {int m,c; cout<<"输入编码必须小于公开模数:"<<r<<endl; cout<<"输入明文编码:";cin>>m; m=input(m); cout<<"密钥 "<<"sk="<<sk<<",pk="<<pk<<endl; cout<<"请输入密钥sk: ";cin>>c; c=pf_c(m,c); cout<<"原编码:"<<m<<" 密文编码:"<<c<<endl; } void pf_c2() {int m,c; cout<<"输入编码必须小于公开模数:"<<r<<endl; cout<<"输入密文编码:";cin>>m; m=input(m); cout<<"密钥 "<<"sk="<<sk<<" pk="<<pk<<endl; cout<<"请输入密钥pk: ";cin>>c; c=pf_c(m,c); cout<<"原编码:"<<m<<" 明文编码:"<<c<<endl; } void use() {cout<<endl; cout<<" 学号:xxxxxx,姓名: yyyyyyyyy"<<endl; cout<<"--------------------------------------"<<endl; cout<<" 1. 产生素数输入"<<endl; cout<<" 2. 产生密钥输入"<<endl; cout<<" 3. 加密信息输入"<<endl; cout<<" 4. 解密信息输入"<<endl; cout<<" 0. 退出运行输入"<<endl; cout<<"--------------------------------------"<<endl; } void main() {char c; use(); do { cin>>c; switch(c) { case '1':primes();use();break; case '2':ckey();use();break; case '3':pf_c1();use();break; case '4':pf_c2();use(); } }while(c=='1'||c=='2'||c=='3'||c=='4'); }