RSA简单加密解密

简介:
  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 }
复制代码
转载自:http://www.cnblogs.com/ziwuge/archive/2011/09/18/2180492.html



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值