RSA算法 - Tsn_Tse
1、公钥密码体制的概念由Diffie和Hellman于1976年提出,用于解决对称密码体制中密钥分配的问题。在公钥密码体制中,密钥被分为公钥与私钥,公钥是公开的,用于加密;私钥是保密的,用于解密。经过四十余年的研究发展,RSA密码、ElGamal密码、椭圆曲线密码等等公钥密码体制在商业、军事上都已经得到了广泛的应用。
2、RSA密码由R. Rivest、A. Shamir和L. Adleman于1977年提出,是最著名的公钥密码,能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。RSA密码的安全性基于这样一个事实:将两个大素数p,q相乘十分容易,但对其乘积N=pq作因子分解却极其困难。在本实验中,假设p,q均为len比特素数,具体描述如下:
系统参数
大素数p、q:len比特素数(即 且p、q为素数)
乘积N:N = p*q,约为2*len比特
N的欧拉函数值:
公钥
(N,e):其中e满足1<e<且gcd (e,
) = 1
私钥
(N,d):其中d满足1<d<且
,即
明文
正整数m:满足1<m<N-1
加密
密文
解密
密文
RSA密钥生成
- 生成指定bit数的大素数p,q,步骤如下:
1)生成指定bit数的随机奇数A
2)利用MillerRabin素性检测算法判断A是否为素数,若通
过,令p=A,否则返回1)继续做,直到通过为止
3)利用同样的方法生成q
单次MillerRabin素性检测算法:
要测试N是否为素数,首先将N-1分解成
再随机选择,若对所有的
,都有
则N是合数,否则,有不小于3/4的概率是素数。
多次MillerRabin素性检测算法:
循环调用单次MillerRabin素性检测算法,若调用次数为loop,则合数通过素性测试(即该算法错误概率)将不超过(1/4)^loop,本次实验中,建议loop取20即可。
参考代码:
1 #include <iostream> 2 #include <time.h> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <math.h> 6 7 #define SIZE 68 8 #define MIN 0 9 #define MAX 255 10 11 using namespace std; 12 13 typedef struct Bigint 14 { 15 unsigned char num[SIZE]; 16 }Bigint; 17 18 typedef struct Bigint2 19 { 20 unsigned char num[2*SIZE]; 21 }bigint2; 22 23 Bigint BigRand(int bytes);//随机生成一个bit为8*bytes的数 24 Bigint BigRand(Bigint n);//生成1到n之间的随机数 25 void Print(Bigint a);//输出Bigint a 26 void Print(Bigint2 a);//输出Bigint2 a 27 int Compare(Bigint a,Bigint b);//比较a,b大小 28 int Compare(Bigint2 a,Bigint2 b);//比较a,b大小 29 Bigint ByteMoveLeft(Bigint a,int n);//将a扩大n*256倍后输出 30 Bigint2 ByteMoveLeft(Bigint2 a,int n);//将a扩大n*256倍后输出 31 void BitMoveRight(Bigint &a);//缩小一个比特(2倍) 32 Bigint Add(Bigint a,Bigint b);//Bigint a与b相加 33 Bigint Sub(Bigint a,Bigint b);//Bigint a-b 34 Bigint2 Sub(Bigint2 a,Bigint2 b);//Bigint2 a-b 35 Bigint2 Mul(Bigint a,Bigint b);//a*b 36 Bigint Div(Bigint a,Bigint b);//Bigint a/b 37 void Print10(Bigint a);//以10进制输出Bigint a 38 void Print10(Bigint2 a);//以10进制数处Bigint2 a 39 int Length(Bigint a);//输出a的长度 40 int Length(Bigint2 a); 41 Bigint2 Mod(Bigint2 a, Bigint2 b); // 求余: 输入a,b, 返回 a % b 42 Bigint Mod(Bigint a, Bigint b);// 求余: 输入a,b, 返回 a % b 43 void Copy(Bigint &a, Bigint b);//复制 44 Bigint2 Extend(Bigint a);//扩充数组 45 Bigint Narrow(Bigint2 a);//截断数组 46 Bigint AddMod(Bigint a,Bigint b,Bigint n);//计算(a+b)mod n 47 Bigint SubMod(Bigint a,Bigint b,Bigint n);//计算(a-b)mod n(a>b) 48 Bigint Sub2Mod(Bigint a,Bigint b,Bigint n);//计算(a-b)mod n 49 Bigint MulMod(Bigint a,Bigint b,Bigint n);//计算(a*b)mod n 50 Bigint PowMod(Bigint a,Bigint b,Bigint n);//计算(a^b)mod n 51 bool MillerRabinKnl(Bigint &n); //单次检测, 通过返回1, 否则返回0 52 bool MillerRabin(Bigint &n, long loop); //多次素性检测 53 Bigint get1n(int bytes);//随机生成一个长为8*bytes的奇数 54 Bigint Encrypt(Bigint m, Bigint e, Bigint N); //计算c = m^e mod N 55 Bigint Decrypt(Bigint c, Bigint d, Bigint N); //计算m = c^d mod N 56 57 58 59 Bigint BigRand(int bytes)//随机生成一个bit为8*bytes的数 60 { 61 Bigint pq; 62 srand((unsigned)time(NULL)); 63 for(int i=0;i<bytes;i++) 64 { 65 pq.num[i]=(unsigned char)(rand()%(MAX-MIN+1)+MIN); 66 } 67 for(int i=bytes;i<SIZE;i++) 68 pq.num[i]=\'\0\'; 69 return pq; 70 } 71 72 int Length(Bigint a) 73 { 74 int len; 75 for(int i=SIZE-1;i>=0;i--) 76 { 77 if(a.num[i]!=\'\0\') 78 { 79 len=i+1; 80 break; 81 } 82 else 83 len=i; 84 } 85 return len; 86 } 87 88 int Length(Bigint2 a) 89 { 90 int len; 91 for(int i=2*SIZE-1;i>=0;i--) 92 { 93 if(a.num[i]!=\'\0\') 94 { 95 len=i+1; 96 break; 97 } 98 else 99 len=i; 100 } 101 return len; 102 } 103 104 void Copy(Bigint &a,Bigint b) 105 { 106 for(int i=0;i<SIZE;i++) 107 { 108 a.num[i]=b.num[i]; 109 } 110 return; 111 } 112 113 Bigint2 Extend(Bigint a) 114 { 115 Bigint2 b={0}; 116 for(int i=0;i<Length(a);i++) 117 { 118 b.num[i]=a.num[i]; 119 } 120 return b; 121 } 122 123 Bigint Narrow(Bigint2 a) 124 { 125 Bigint b={0}; 126 for(int i=0;i<SIZE;i++) 127 { 128 b.num[i]=a.num[i]; 129 } 130 return b; 131 } 132 133 Bigint BigRand(Bigint n)//生成1到n之间的随机数 134 { 135 Bigint a; 136 int len; 137 srand((unsigned)time(NULL)); 138 len=rand()%(Length(n)-1)+1; 139 a=BigRand(len); 140 while(Compare(a,n)>=0||(Length(a)==1&&(int)a.num[0]==0)) 141 { 142 srand((unsigned)time(NULL)); 143 len=rand()%(Length(n)-1)+1; 144 a=BigRand(len); 145 } 146 return a; 147 } 148 149 void Print(Bigint a)//输出Bigint a; 150 { 151 if(Length(a)==0) 152 cout<<\'0\'<<endl; 153 else 154 for(int i=Length(a)-1;i>=0;i--) 155 { 156 cout.width(3); 157 cout<<(int)a.num[i]<<\',\'; 158 } 159 cout<<endl; 160 } 161 162 void Print(Bigint2 a)//输出Bigint2 a; 163 { 164 if(Length(a)==0) 165 cout<<\'0\'<<endl; 166 else 167 for(int i=Length(a)-1;i>=0;i--) 168 { 169 cout.width(3); 170 cout<<(int)a.num[i]<<\',\'; 171 } 172 cout<<endl; 173 } 174 175 int Compare(Bigint a,Bigint b)//比较a与b的大小 176 { 177 int max,len_a,len_b; 178 len_a=Length(a); 179 len_b=Length(b); 180 if(len_a>len_b) 181 return 1; 182 else if(len_a<len_b) 183 return -1; 184 else 185 max=len_a; 186 for(int i=max-1;i>=0;i--) 187 { 188 if(a.num[i]>b.num[i]) 189 return 1; 190 if(a.num[i]<b.num[i]) 191 return -1; 192 } 193 return 0; 194 } 195 196 int Compare(Bigint2 a,Bigint2 b)//比较大小 197 { 198 int max,len_a,len_b; 199 len_a=Length(a); 200 len_b=Length(b); 201 if(len_a>len_b) 202 return 1; 203 else if(len_a<len_b) 204 return -1; 205 else 206 max=len_a; 207 for(int i=max-1;i>=0;i--) 208 { 209 if(a.num[i]>b.num[i]) 210 return 1; 211 if(a.num[i]<b.num[i]) 212 return -1; 213 } 214 return 0; 215 } 216 217 Bigint Add(Bigint a,Bigint b)//Bigint a+b 218 { 219 Bigint c; 220 int Carry=0,temp,i,max; 221 for(int i=0;i<SIZE;i++) 222 { 223 temp=(int)a.num[i]+(int)b.num[i]+Carry; 224 Carry=temp/256; 225 temp=temp%256; 226 c.num[i]=(char)temp; 227 } 228 return c; 229 } 230 231 Bigint Sub(Bigint a,Bigint b)//Bigint a-b 232 { 233 int temp,i,Carry=0,n; 234 Bigint c; 235 n=Compare(a,b); 236 if(n==-1) 237 { 238 cout<<"Subtract error!"<<endl; 239 return a; 240 } 241 else//执行a-b 242 { 243 for(i=0;i<SIZE;i++) 244 { 245 if((int)a.num[i]-Carry>=(int)b.num[i]) 246 { 247 temp=(int)a.num[i]-Carry-(int)b.num[i]; 248 Carry=0; 249 } 250 else 251 { 252 temp=(int)a.num[i]-Carry+256-(int)b.num[i]; 253 Carry=1; 254 } 255 c.num[i]=(unsigned char)temp; 256 } 257 } 258 return c; 259 } 260 261 Bigint2 Sub(Bigint2 a,Bigint2 b)//Bigint2 a-b 262 { 263 int temp,i,Carry=0,n; 264 Bigint2 c; 265 n=Compare(a,b); 266 if(n==-1) 267 { 268 cout<<"Subtract error!"<<endl; 269 return a; 270 } 271 else//执行a-b 272 { 273 for(i=0;i<2*SIZE;i++) 274 { 275 if((int)a.num[i]-Carry>=(int)b.num[i]) 276 { 277 temp=(int)a.num[i]-Carry-(int)b.num[i]; 278 Carry=0; 279 } 280 else 281 { 282 temp=(int)a.num[i]-Carry+256-(int)b.num[i]; 283 Carry=1; 284 } 285 c.num[i]=(unsigned char)temp; 286 } 287 } 288 return c; 289 } 290 291 Bigint2 Mul(Bigint a,Bigint b)//a*b 292 { 293 Bigint2 c={0}; 294 int Carry=0,temp; 295 int i,j; 296 for(i=0;i<SIZE;i++) 297 { 298 for(j=0;j<SIZE;j++) 299 { 300 temp=(int)a.num[i]*(int)b.num[j]+(int)c.num[i+j]+Carry; 301 Carry=temp/256; 302 temp=temp%256; 303 c.num[i+j]=(unsigned char)temp; 304 } 305 } 306 c.num[2*SIZE-1]=(unsigned char)Carry; 307 return c; 308 } 309 310 Bigint ByteMoveLeft(Bigint a,int n)//将a扩大n*256倍后输出 311 { 312 Bigint c={0}; 313 int i; 314 for(i=Length(a)-1;i>=0;i--) 315 { 316 c.num[i+n]=a.num[i]; 317 } 318 for(i=0;i<n;i++) 319 c.num[i]=\'\0\'; 320 return c; 321 } 322 323 Bigint2 ByteMoveLeft(Bigint2 a,int n)//将a扩大n*256倍后输出 324 { 325 Bigint2 c={0}; 326 int i; 327 for(i=Length(a)-1;i>=0;i--) 328 { 329 c.num[i+n]=a.num[i]; 330 } 331 for(i=0;i<n;i++) 332 c.num[i]=\'\0\'; 333 return c; 334 } 335 336 void BitMoveRight(Bigint &a)//缩小一个比特(2倍) 337 { 338 Bigint b={2}; 339 a=Div(a,b); 340 return; 341 } 342 343 Bigint Div(Bigint a,Bigint b)//Bigint a/b 344 { 345 int len; 346 Bigint B={0}; 347 Bigint c={0}; 348 len=Length(a)-Length(b); 349 while(len>=0) 350 { 351 B=ByteMoveLeft(b,len); 352 while(Compare(a,B)>=0) 353 { 354 a=Sub(a,B); 355 c.num[len]++; 356 } 357 len--; 358 } 359 return c; 360 } 361 362 Bigint Mod(Bigint a,Bigint b)//计算Bigint a%b 363 { 364 if(Compare(a,b)<0) 365 return a; 366 else 367 { 368 Bigint B={0}; 369 int len=Length(a)-Length(b); 370 while(len>=0) 371 { 372 B=ByteMoveLeft(b,len); 373 while(Compare(a,B)>=0) 374 { 375 a=Sub(a,B); 376 } 377 len--; 378 } 379 } 380 return a; 381 } 382 383 Bigint2 Mod(Bigint2 a,Bigint2 b)//计算Bigint2 a%b 384 { 385 if(Compare(a,b)<0) 386 return a; 387 else 388 { 389 Bigint2 B={0}; 390 int len=Length(a)-Length(b); 391 while(len>=0) 392 { 393 B=ByteMoveLeft(b,len); 394 while(Compare(a,B)>=0) 395 { 396 a=Sub(a,B); 397 } 398 len--; 399 } 400 } 401 return a; 402 } 403 404 Bigint Mod10(Bigint a)//Bigint a对10做模运算 405 { 406 Bigint n={0}; 407 for(int i=0;i<Length(a);i++) 408 { 409 n.num[0]=((int)n.num[0]%10+(((int)a.num[i]%10)*(int)pow(6,i))%10)%10; 410 } 411 return n; 412 } 413 414 void Print10(Bigint a) //十进制打印输出 415 { 416 int res[2000]; 417 int i = 0; 418 Bigint b = {0}; 419 Bigint c = {10}; 420 if(Length(a) == 0) //若a==0,则输出0 421 { 422 cout<<0<<endl; 423 return; 424 } 425 Bigint d={0}; 426 while(Compare(a,b) == 1) 427 { 428 d=Mod(a,c); 429 res[i]=(int)d.num[0]; 430 a = Div(a,c); 431 i++; 432 } 433 for(int j = i-1; j>=0; j--) 434 { 435 cout<<res[j]; 436 } 437 cout<<endl; 438 } 439 440 Bigint AddMod(Bigint a,Bigint b,Bigint n) 441 { 442 Bigint c={0}; 443 c=Add(a,b); 444 c=Mod(c,n); 445 return c; 446 } 447 448 Bigint SubMod(Bigint a,Bigint b,Bigint n)//计算(a-b)mod n(a>b) 449 { 450 Bigint c={0}; 451 if(Compare(a,b)<0) 452 { 453 cout<<"ERROR!"<<endl; 454 return c; 455 } 456 else 457 { 458 c=Sub(a,b); 459 c=Mod(c,n); 460 } 461 return c; 462 } 463 464 Bigint Sub2Mod(Bigint a,Bigint b,Bigint n)//计算(a-b)mod n 465 { 466 Bigint c={0}; 467 if(Compare(a,b)<0) 468 { 469 c=Sub(Add(a,n),b); 470 c=Mod(c,n); 471 } 472 else 473 { 474 c=Sub(a,b); 475 c=Mod(c,n); 476 } 477 return c; 478 } 479 480 Bigint MulMod(Bigint a,Bigint b,Bigint n)//计算(a*b)mod n 481 { 482 Bigint2 C={0},N={0}; 483 Bigint c={0}; 484 a=Mod(a,n); 485 b=Mod(b,n); 486 C=Mul(a,b); 487 N=Extend(n); 488 C=Mod(C,N); 489 c=Narrow(C); 490 return c; 491 } 492 493 Bigint PowMod(Bigint a,Bigint b,Bigint n)//计算(a^b)mod n 494 { 495 Bigint c = {1}; 496 Bigint temp = {1}; 497 while(Length(b) > 0) 498 { 499 while(!(b.num[0] & 0x01)) 500 { 501 BitMoveRight(b); 502 a = MulMod(a,a,n); 503 } 504 b = Sub(b,temp); 505 c = MulMod(a,c,n); 506 } 507 return c; 508 } 509 510 bool MillerRabinKnl(Bigint &n) //单次检测, 通过返回1, 否则返回0 511 { 512 Bigint b,m,v,temp; 513 Bigint j = {0}; 514 Bigint one = {1}; 515 Bigint two = {2}; 516 Bigint three = {3}; 517 m = Sub(n,one); 518 while(!(m.num[0] & 0x01)) //计算m, j,使得 n-1=2^j * m 519 { 520 j = Add(j,one); 521 BitMoveRight(m); 522 } 523 b = Add(two, BigRand(Sub(n,three))); //随机取一个 524 v = PowMod(b,m,n); //计算 525 if(Compare(v,one) == 0) //若v=1,通过测试 526 return 1; 527 528 Bigint i = {1}; 529 temp = Sub(n,one); 530 while(Compare(v,temp) < 0) //若v<n-1,不通过 531 { 532 if(Compare(i,j) == 0) //若i=j,是合数,不通过 533 return 0; 534 v = MulMod(v,v,n); //, i=i+1 535 i = Add(i,one); 536 } 537 return 1; //若v=n-1, 通过测试 538 } 539 540 bool MillerRabin(Bigint &n, long loop) //多次素性检测 541 { 542 for(long i = 0; i<loop;i++) 543 { 544 if(!MillerRabinKnl(n)) 545 return 0; 546 } 547 return 1; 548 } 549 550 Bigint get1n(int bytes)//随机生成一个长为8*bytes的奇数 551 { 552 Bigint n={0}; 553 while(!(n.num[0] & 0x01)) 554 { 555 n=BigRand(bytes); 556 } 557 return n; 558 } 559 560 bool Inverse(Bigint phiN, Bigint e, Bigint &d) 561 { 562 Bigint zero ={0}; 563 Bigint one = {1}; 564 Bigint y2 = {1}; 565 Bigint x2 = {0}; 566 Bigint x3,y3,t2,t3,q; 567 Copy(x3, phiN); 568 Copy(y3, e); 569 while(1) 570 { 571 if(Length(y3) == 0) //若y3=0,求逆失败,返回0 572 return 0; 573 if(Length(y3) == 1 && y3.num[0] == 1) 574 { //若y3=1,求逆成功,令d=y2,并返回1 575 Copy(d,y2); 576 return 1; 577 } 578 q = Div(x3,y3); //利用与辗转相除法类似的方法 579 t2 = Sub2Mod(x2,MulMod(q,y2,phiN),phiN); 580 //t2 = (x2 - q*y2) mod phiN,模是为了不出现负数 581 t3 = Sub(x3,Narrow(Mul(q,y3))); // t3 = x3-q*y3 582 Copy(x2,y2); 583 Copy(x3,y3); 584 Copy(y2,t2); 585 Copy(y3,t3); 586 } 587 } 588 589 Bigint Encrypt(Bigint m, Bigint e, Bigint N) //计算c = m^e mod N 590 { 591 Bigint c; 592 c=PowMod(m,e,N); 593 return c; 594 } 595 596 Bigint Decrypt(Bigint c, Bigint d, Bigint N) //计算m = c^d mod N 597 { 598 Bigint m; 599 m=PowMod(c,d,N); 600 return m; 601 } 602 603 Bigint GetP_Q(int bytes)//得到8*bytes的pq 604 { 605 Bigint pq={0}; 606 pq=get1n(bytes); 607 while(!(MillerRabin(pq,20))) 608 { 609 pq=get1n(bytes); 610 } 611 return pq; 612 } 613 614 int main() 615 { 616 Bigint p,q,d,m,c,phiN,N,m1; 617 Bigint e={1,0,1}; 618 Bigint one={1}; 619 p=GetP_Q(32); 620 sleep(1); 621 q=GetP_Q(32); 622 N=Narrow(Mul(p,q)); 623 phiN=Narrow(Mul(Sub(p,one),Sub(q,one))); 624 while(!(Inverse(phiN,e,d))) 625 { 626 p=GetP_Q(32); 627 sleep(1); 628 q=GetP_Q(32); 629 N=Narrow(Mul(p,q)); 630 phiN=Narrow(Mul(Sub(p,one),Sub(q,one))); 631 } 632 m=BigRand(64); 633 c=Encrypt(m,e,N); 634 m1=Decrypt(c,d,N); 635 cout<<"生成大素数:"<<endl; 636 cout<<"p="; 637 Print10(p); 638 cout<<"q="; 639 Print10(q); 640 cout<<endl<<"系统的参数是:"<<endl; 641 cout<<"N="; 642 Print10(N); 643 cout<<endl<<"公钥是:"<<endl; 644 cout<<"e="; 645 Print10(e); 646 cout<<endl<<"私钥是:"<<endl; 647 cout<<"d="; 648 Print10(d); 649 cout<<endl<<"明文是:"<<endl; 650 cout<<"m="; 651 m=Mod(m,N); 652 Print10(m); 653 cout<<endl<<"加密得到的密文:"<<endl; 654 cout<<"c="; 655 Print10(c); 656 cout<<endl<<"解密得到的明文:"<<endl; 657 cout<<"m1="; 658 Print10(m1); 659 Bigint a; 660 /*a=MulMod(e,d,phiN); 661 Print10(a);*/ 662 return 0; 663 }
运行后得到的结果(不唯一):