您的位置:首页 > 其它

RSA简单加密解密

2013-07-12 09:57 253 查看
简介:

  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 }




转载自:/article/4970086.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: