简介:
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;
更详解的介绍请自行查阅相关资料....
算法(源码) :(注:本代码只适合小数,不适合大数)
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 else 102 { 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 else 211 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 }