现在的位置: 首页 > 综合 > 正文

RSA简单加密解密

2011年08月21日 ⁄ 综合 ⁄ 共 5446字 ⁄ 字号 评论关闭

简介:
  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 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 }

【参考资料 感谢作者】
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

抱歉!评论已关闭.