RSA简单加密解密

纵饮孤独 提交于 2020-02-13 21:11:18

简介:
  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)是密钥对。
  RSA加解密的算法完全相同,设A为明文,B为密文,则:A=B^e1 mod n;B=A^e2 mod n;
  e1和e2可以互换使用,即:A=B^e2 mod n;B=A^e1 mod n; 

  更详解的介绍请自行查阅相关资料....

算法(源码) :(注:本代码只适合小数,不适合大数)

View Code
  1 #include <stdio.h>  2 #include <iostream>  3 #include <time.h>  4 #include <math.h>  5   6 // PRIMENUMBER指定构造素数数组的元素个数,200以内的素数有39个  7 #define PRIMENUMBER 39  8   9 usingnamespace std; 10  11 bool IsPrime(long PrimeArray[], constlong&nPositiveInteger); 12 void MakePrimeArray(long PrimeArray[], constlong&nPrimeNumber); 13 long PrimeABCalc(constlong&PrimeA, constlong&PrimeB); 14 void GetPrimeAuto( long PrimeArray[], long&PrimeA, long&PrimeB); 15 void GetPrimeHand( long PrimeArray[], long&PrimeA, long&PrimeB); 16 long GCD(long KeyE, long fn); 17 long GetKeyE(long fn); 18 long GetKeyD(long KeyE, long fn); 19 long Encrypt( long KeyE, long n, long cleartext); 20 long Decipher( long KeyD, long n, long ciphertext); 21  22 // 主函数 23 long main(long argc, char* argv[]) 24 { 25 long MyPrimeArray[PRIMENUMBER] = {0}; 26     MakePrimeArray(MyPrimeArray, PRIMENUMBER); 27 long PrimeA =0; 28 long PrimeB =0; 29 long n =0; 30 long PrimeAB =0; 31 long e =0; 32 long d =0; 33 long cleartext =0; 34 long ciphertext =0; 35 long nSelect =0; 36     cout<<"素数产生方式(1~100):"; 37     cout<<"1 手动指定   "<<"2 自动随机\t"; 38     cout<<"选择:"; 39     cin>>nSelect; 40  41 if (1== nSelect) 42         GetPrimeHand(MyPrimeArray, PrimeA, PrimeB); 43 elseif (2== nSelect) 44         GetPrimeAuto(MyPrimeArray, PrimeA, PrimeB); 45 else 46         cout<<"选择错误!"<<endl; 47  48     cout<<"随机数 p: "<<PrimeA<<"\tq: "<<PrimeB<<endl; 49     n = PrimeA * PrimeB; 50     cout<<"素数的乘积n = pq: "<<n<<"\t"; 51     PrimeAB = PrimeABCalc(PrimeA, PrimeB); 52     cout<<"值f(n) = (p-1)(q-1): "<<PrimeAB<<endl; 53     e = GetKeyE(PrimeAB); 54     cout<<"公钥e: "<<e<<"\t"; 55     d = GetKeyD(e, PrimeAB); 56     cout<<"密钥d: "<<d<<endl; 57     cout<<"输入一个正整数明文:"; 58     cin>>cleartext; 59     ciphertext = Encrypt(e, n, cleartext); 60     cout<<"加密后密文: "<<ciphertext<<endl; 61     cleartext = Decipher(d, n, ciphertext); 62     cout<<"解密后明文: "<<cleartext<<endl; 63     cout<<"\n该RSA加密仅做参考,运算时可能会溢出."<<endl; 64     system("Pause"); 65 return0; 66 } 67  68 // 计算f(n)=(p-1)(q-1) 69 long PrimeABCalc(constlong&PrimeA, constlong&PrimeB) 70 { 71 return ((PrimeA -1) * (PrimeB -1)); 72 } 73  74 // 手动输入素数 75 void GetPrimeHand( long PrimeArray[], long&PrimeA, long&PrimeB ) 76 { 77 bool PrimeTrue =true; 78 // 输入第一个素数 79 do  80     { 81 if (PrimeTrue) 82         { 83             cout<<"请输入第一个素数:"; 84         }  85 else 86         { 87             cout<<"该数不是素数,请重新输入第一个素数:"; 88         } 89         cin>>PrimeA; 90         PrimeTrue = IsPrime(PrimeArray, PrimeA); 91     } while (!PrimeTrue); 92      93     PrimeTrue =true; 94 // 输入第二个素数 95 do  96     { 97 if (PrimeTrue) 98         { 99             cout<<"请输入第二个素数:";100         } 101 else102         {103             cout<<"该数不是素数,请重新输入第二个素数:";104         }105         cin>>PrimeB;106         PrimeTrue = IsPrime(PrimeArray, PrimeB);107     } while (!PrimeTrue);108 while (PrimeA == PrimeB)109     {110 do 111         {112             cout<<"请重新输入第二个素数:";113             cin>>PrimeB;114         } while (!IsPrime(PrimeArray, PrimeB));115     }116 return;117 }118 119 // 自动产生1~100的随机数120 void GetPrimeAuto( long PrimeArray[], long&PrimeA, long&PrimeB)121 {122     srand((unsigned)time(NULL));123 do 124     {125         PrimeA = rand()%100;126     } while (!IsPrime(PrimeArray, PrimeA));127     128 do 129     {130         PrimeB = rand()%100;131     } while (!IsPrime(PrimeArray, PrimeB));132     133 while (PrimeA == PrimeB)134     {135 do 136         {137             PrimeB = rand()%200;138         } while (!IsPrime(PrimeArray, PrimeB));139     }140 return;141 }142 143 // 判断是否是素数144 bool IsPrime(long PrimeArray[], constlong&nPositiveInteger)145 {146 if(nPositiveInteger <2) 147 returnfalse;148 for(long i =0; PrimeArray[i]*PrimeArray[i] <= nPositiveInteger; ++i)149     {150 if(nPositiveInteger%PrimeArray[i] ==0)151 returnfalse;152     }153 returntrue;154 }155 156 // 构造素数序列primes[]157 void MakePrimeArray(long PrimeArray[], constlong&nPrimeNumber)158 {159 long i, cnt;160     PrimeArray[0] =2;161     PrimeArray[1] =3;162 for(i =5, cnt =2; cnt < nPrimeNumber; i +=2)163     {164 bool flag =true;165         flag = IsPrime(PrimeArray, i);166 if(flag)167             PrimeArray[cnt++] = i;168     }169 }170 171 // 找一个与f(n)互质的数e,且1<e<f(n),此处随机产生172 long GetKeyE( long fn )173 {174 long KeyE =0;175 long SelectKeyE =0;176     177     cout<<"产生公钥e方式: "<<"1 随机   2 顺序"<<"\t";178 while (1)179     {180         cout<<"选择: ";181         cin>>SelectKeyE;182 if ( 1== SelectKeyE)183         {184             srand(NULL);185 while(1)186             {187 /*KeyE = rand()%fn;    // 如果随机可能会造成后面幂运算溢出*/188                 KeyE++;189 if ((KeyE>=2) && (GCD(KeyE, fn) ==1))190 break;191 if ( KeyE > fn)192 break;193             }194 break;195         }196 elseif ( 2== SelectKeyE)197         {198 long i =2;199 while (1)200             {201 if (GCD(i, fn) ==1)202                 {203                     KeyE = i;204 break;205                 }206                 i++;207             }208 break;209         }210 else211             cout<<"选择有误!"<<endl;212     }213 return KeyE;    214 }215 216 // 求两数最大公约数,若为1则说明两数为互质数217 long GCD( long KeyE, long fn )218 {219 long iDividend = fn;        // 被除数220 long iDivisor = KeyE;    // 除数221 long iResidual = iDividend%iDivisor;        //余数222 // 辗转相除法223 while (iResidual !=0)224     {225 //将除数作为被除数226         iDividend=iDivisor;227 //把余数作为除数228         iDivisor=iResidual;229 //求新的余数230         iResidual=iDividend%iDivisor;231     }232 return iDivisor;233 }234 235 // 计算d,使得d*e≡1 mod f(n).这个公式也可以表达为d ≡e-1 mod f(n)236 long GetKeyD( long KeyE, long fn )237 {238 long iKeyD =0;239 long Ji =0;240     srand(NULL);241 do 242     {243 /*iKeyD = rand();    // 如果随机可能会造成后面的幂运算溢出*/244         iKeyD++;245         Ji = iKeyD * KeyE;246     } while (!(GCD(Ji, fn) ==1&& ((Ji+fn)%fn ==1)));247 return iKeyD;248 }249 250 // 加密251 long Encrypt( long KeyE, long n, long cleartext )252 {253 long ciphertext =0;254     ciphertext = ((long)pow(cleartext, KeyE)%n);255 return ciphertext;256 }257 258 // 解密259 long Decipher( long KeyD, long n, long ciphertext )260 {261 //     long cleartext = 0;262 //     cleartext = ((long)pow(ciphertext, KeyD)%n);263 //     return cleartext;264 // 下面是用的模幂运算的简便算法,我自己的代码会造成计算溢出.265 long cleartext =1;266     KeyD = KeyD +1;267 while( KeyD !=1)268     {269         cleartext = cleartext * ciphertext;270         cleartext = cleartext % n;271         KeyD--;272     }273 return cleartext;274 }

【参考资料 感谢作者】
RSA加密算法(转) :http://hi.baidu.com/%CE%E2%D2%A2%C1%D6/blog/item/414229ce214a7c0693457e18.html 
RSA算法_百科:http://baike.baidu.com/view/7520.htm
论文:RSA算法的分析与实现:http://ces.ustc.edu.cn/jpg/pap/xbq/index.htm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!