简介:
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 Code1 #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
来源:https://www.cnblogs.com/ziwuge/archive/2011/09/18/2180492.html